package com.mzj.saas.mservice.eligible.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mzj.saas.commons.*;
import com.mzj.saas.commons.enums.BacklogItemTypeEnum;
import com.mzj.saas.commons.enums.EligibleApplyTypeEnum;
import com.mzj.saas.commons.enums.EligibleMatchTypeEnum;
import com.mzj.saas.commons.enums.OSSUploadFileTypeEnum;
import com.mzj.saas.commons.util.ConvertUtils;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.config.oss.OssConfig;
import com.mzj.saas.mservice.application.entity.ApprovalProcess;
import com.mzj.saas.mservice.application.entity.ApprovalProcessUser;
import com.mzj.saas.mservice.application.repository.ApprovalProcessRepository;
import com.mzj.saas.mservice.application.repository.ApprovalProcessUserRepository;
import com.mzj.saas.mservice.area.entity.Area;
import com.mzj.saas.mservice.area.repository.AreaRepository;
import com.mzj.saas.mservice.backlog.entity.BacklogItem;
import com.mzj.saas.mservice.backlog.entity.BacklogItemApprove;
import com.mzj.saas.mservice.backlog.entity.BacklogItemWaitRent;
import com.mzj.saas.mservice.backlog.repository.BacklogItemApproveRepository;
import com.mzj.saas.mservice.backlog.repository.BacklogItemRepository;
import com.mzj.saas.mservice.backlog.repository.BacklogItemWaitRentRepository;
import com.mzj.saas.mservice.department.entity.Department;
import com.mzj.saas.mservice.department.repository.DepartmentRepository;
import com.mzj.saas.mservice.eligible.entity.*;
import com.mzj.saas.mservice.eligible.repository.*;
import com.mzj.saas.mservice.eligible.vo.*;
import com.mzj.saas.mservice.house.entity.Cohabit;
import com.mzj.saas.mservice.house.repository.CohabitRepository;
import com.mzj.saas.mservice.house.vo.CohabitVO;
import com.mzj.saas.mservice.oss.service.OSSService;
import com.mzj.saas.mservice.sys.entity.AppUser;
import com.mzj.saas.mservice.sys.entity.User;
import com.mzj.saas.mservice.sys.repository.AppUserRepository;
import com.mzj.saas.mservice.sys.repository.UserRepository;
import com.mzj.saas.mservice.sys.service.AppUserService;
import com.mzj.saas.mservice.sys.service.UserService;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class EligibleService {
    private static final Logger log = LoggerFactory.getLogger(EligibleService.class);

    private static final String ELIGIBLE_ORDER = " ORDER BY a.apply_time DESC";
    private static final String SQL_PAGE = " LIMIT ? OFFSET ?";

    @Autowired
    private RedisService redisService;
    @Autowired
    private UserService userService;
    @Autowired
    private AppUserRepository appUserRepository;
    @Autowired
    private EligibleRepository eligibleRepository;
    @Autowired
    private ApplyAuditRepository applyAuditRepository;
    @Autowired
    private OSSService ossService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private CohabitRepository cohabitRepository;
    @Autowired
    private OssConfig ossConfig;
    @Autowired
    private ApprovalProcessUserRepository approvalProcessUserRepository;
    @Autowired
    private ApprovalProcessRepository approvalProcessRepository;
    @Autowired
    @Qualifier("stringRedisTemplate")
    private StringRedisTemplate redisTemplate;
    @Autowired
    private HouseApplyMaterialRepository houseApplyMaterialRepository;
    @Autowired
    private DepartmentRepository departmentRepository;
    @Autowired
    private AreaRepository areaRepository;
    @Autowired
    private HouseCohabitMaterialRepository houseCohabitMaterialRepository;
    @Autowired
    private HouseApplyFlowRepository houseApplyFlowRepository;
    @Autowired
    private AppUserService appUserService;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private BacklogItemRepository backlogItemRepository;
    @Autowired
    private BacklogItemApproveRepository backlogItemApproveRepository;
    @Autowired
    private HouseApplyFlowOldRepository houseApplyFlowOldRepository;
    @Autowired
    private HouseApplyMaterialOldRepository houseApplyMaterialOldRepository;
    @Autowired
    private HouseCohabitMaterialOldRepository houseCohabitMaterialOldRepository;
    @Autowired
    private EligibleOldRepository eligibleOldRepository;
    @Autowired
    private ApplyAuditOldRepository applyAuditOldRepository;
    @Autowired
    private BacklogItemWaitRentRepository backlogItemWaitRentRepository;
    /**
     * 权限状态验证,实现了判断用户是否有权限进行公租房的申请
     *
     * @param accessToken 权限鉴定
     * @return
     */
    public ResultBean<Map<String, Object>> verify(String accessToken) {
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取用户ID
            String userId = tokenRedisVo.getId();
            //获取用户登录类型：1企业用户登录 2普通用户登录
            Integer loginType = tokenRedisVo.getLoginType();
            //根据用户ID和登录类型查询用户数据
            AppUser user = appUserService.findByIdAndStatus(userId, 1, loginType);
            if (user == null) {
                return ResultBean.failedResultOfParamWithMsg("用户不存在");
            }
            //获取用户是否实名认证：0未认证 1已认证
            Integer certificationStatus = user.getCertificationStatus();

            Map<String, Object> map = new HashMap<>();
            // 判断是否实名认证 0未认证 1已认证
            if (certificationStatus == null || certificationStatus == 0) {
                return ResultBean.failedResultWithMsg("请先进行实名认证");
            } else {
                String cardNumber = user.getCardNumber();
                // 跳转标识：true 资格列表页面,false 申请页面
                Boolean flag = false;
                if (loginType == 1) {
                    Long enterpriseId = tokenRedisVo.getEnterpriseId();
                    //根据用户ID查询出用户层级权限
                    Optional<Department> departmentOptional = departmentRepository.findById(enterpriseId);
                    if (!departmentOptional.isPresent()) {
                        return ResultBean.failedResultWithMsg("用户所属机构不存在");
                    }
                    map.put("orgName", departmentOptional.get().getName());
                    // 判断是否已有申请记录，根据身份证或者企业ID判断查询是否有申请记录
                    List<Map<String, Object>> list = jdbcTemplate.queryForList(
                            "SELECT * FROM saas_house_eligible_apply WHERE (org_id = ? OR card_number = ?) AND apply_status != 0",
                            enterpriseId, cardNumber);
                    if (list != null && list.size() != 0) {
                        flag = true;
                        map.put("flag", flag);
                    } else {// 跳转申请页面
                        map.put("flag", flag);
                    }

                    map.put("loginType", loginType);
                } else if (loginType == 2) {
                    map.put("orgName", null);
                    // 判断是否已有申请记录，根据身份证判断查询是否有申请记录
                    List<Map<String, Object>> list = jdbcTemplate.queryForList(
                            "SELECT * FROM saas_house_eligible_apply where card_number = ? and apply_status != 0",
                            cardNumber);
                    if (list != null && list.size() != 0) {
                        flag = true;
                        map.put("flag", flag);
                    } else {
                        map.put("flag", flag);
                    }
                    map.put("loginType", loginType);
                }
                //把数据返回给前端页面
                return ResultBean.successfulResult(map);
            }
        } catch (Exception e) {
            //记录报错日志
            log.error("EligibleService verify Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }
    /**
     * 证明材料上传
     *
     * @param accessToken  权限鉴定
     * @param cardNumber  身份证
     * @param uploadType  人员类型：0承租人 1同住人
     * @param type        材料类型：1户籍状况证明材料 2婚姻状况证明材料 3工作证明材料 4收入状况证明材料 5住房状况证明材料 6财产状况证明材料 7优先保障人群证明材料
     * @param file        文件
     * @return
     */
    public ResultBean<Object> uploadFile(String accessToken, String cardNumber, Integer uploadType, Integer type,
                                         MultipartFile file) {
        try {
            //判断前端传过来的数据是否为空
            if (StringUtils.isBlank(cardNumber)) {
                return ResultBean.failedResultOfParamWithMsg("身份证号为空");
            }
            if (uploadType == null) {
                return ResultBean.failedResultOfParamWithMsg("人员类型为空");
            }
            if (type == null) {
                return ResultBean.failedResultOfParamWithMsg("上传文件类型为空");
            }
            if (file == null) {
                return ResultBean.failedResultOfParamWithMsg("文件为空");
            }
            //判断人员类型
            String string = "";
            if (uploadType == 0) {
                string = "ELIGIBLE:";
            } else if (uploadType == 1) {
                string = "COHABIT:";
            }

            // 上传文件
            ResultBean<Object> objectResultBean = ossService.putFile(ossConfig.getOssBucketName(), file,
                    OSSUploadFileTypeEnum.PROVE.toString());
            String fileKey = objectResultBean.getResultData().toString();

            // 获取redis已上传文件fileKey
            String value = (String) redisTemplate.opsForHash().get(string + cardNumber, type.toString());
            if (!StringUtils.isBlank(value)) {
                String[] split = value.split(",");
                // 添加fileKey到redis缓存
                List<String> list = new ArrayList<>(Arrays.asList(split));
                list.add(fileKey);
                String str = StringUtils.join(list.toArray(), ",");
                redisTemplate.opsForHash().put(string + cardNumber, type.toString(), str);
            } else {
                redisTemplate.opsForHash().put(string + cardNumber, type.toString(), fileKey);
            }

            return ResultBean.successfulResult(fileKey);
        } catch (Exception e) {
            log.error("EligibleService uploadFile Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }
    /**
     * 上传单位证件照片,实现了对公租房单位的公租房资格申请
     *
     * @param accessToken 权限鉴定
     * @param file 文件
     * @return
     */
    public ResultBean<Object> uploadUnitPic(String accessToken, String orgUserMobile, MultipartFile file) {
        try {
            //判断手机号是否为空
            if (StringUtils.isBlank(orgUserMobile)) {
                return ResultBean.failedResultOfParamWithMsg("手机号码为空");
            }
            //判断文件是否为空
            if (file == null) {
                return ResultBean.failedResultOfParamWithMsg("文件为空");
            }

            // 如果有缓存，先删除上传文件
            Object object = redisTemplate.opsForValue().get("unitPic:fileKey:" + orgUserMobile);
            if (object != null) {
                String fileKey = object.toString();
                ossService.deleteObject(ossConfig.getOssBucketName(), fileKey);
            }
            // 上传成功后，重新设置缓存
            ResultBean<Object> objectResultBean = ossService.putFile(ossConfig.getOssBucketName(), file,
                    OSSUploadFileTypeEnum.PROVE.toString());
            String code = objectResultBean.getCode();
            String msg = objectResultBean.getMsg();
            if (!code.equals(StatusCode.SUCCESS_CODE_10000.getErrorCode())) {
                return ResultBean.failedResultWithCodeAndMsg(code, msg);
            } else {
                String fileKey = objectResultBean.getResultData().toString();
                redisTemplate.opsForValue().set("unitPic:fileKey:" + orgUserMobile, fileKey, 5, TimeUnit.MINUTES);
                String url = ossService.getOssFilePath(fileKey);
                return ResultBean.successfulResult(url);
            }

        } catch (Exception e) {
            log.error("EligibleService uploadUnitPic Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public List<String> listCompare(List<String> menuOneList, List<String> resourceList) {
        Map<String, Integer> map = new HashMap<String, Integer>(resourceList.size());
        List<String> differentList = new ArrayList<String>();
        for (String resource : resourceList) {
            map.put(resource, 1);
        }
        for (String resource1 : menuOneList) {
            if (map.get(resource1) == null) {
                differentList.add(resource1);
            }
        }
        return differentList;
    }

    @Transactional
    public ResultBean<EligibleReturnVO> saveEligible(String accessToken, EligibleVO vo) {
        log.info("新增资格申请 saveEligible vo={}", JSONObject.toJSONString(vo));

        try {
            Integer type = vo.getType();
            if (type == null) {
                return ResultBean.failedResultOfParamWithMsg("申请类型为空");
            }
            if (vo.getProvinceId() == null || vo.getCityId() == null || vo.getDistrictId() == null
                    || vo.getStreetId() == null || vo.getCommunityId() == null) {
                return ResultBean.failedResultOfParamWithMsg("区域为空");
            }
            if (vo.getAttributeType() == null) {
                return ResultBean.failedResultOfParamWithMsg("人员属性为空");
            }
            if (StringUtils.isBlank(vo.getName()) || StringUtils.isBlank(vo.getEthnic())
                    || StringUtils.isBlank(vo.getBirthDate()) || StringUtils.isBlank(vo.getCardNumber())
                    || StringUtils.isBlank(vo.getCardAddress())) {
                return ResultBean.failedResultOfParamWithMsg("身份证信息为空");
            }
            if (vo.getDomicileProvinceId() == null || vo.getDomicileCityId() == null
                    || vo.getDomicileDistrictId() == null) {
                return ResultBean.failedResultOfParamWithMsg("户籍地为空");
            }
            if (vo.getFamilyTiesType() == null) {
                return ResultBean.failedResultOfParamWithMsg("家庭关系为空");
            }
            if (vo.getCultureType() == null) {
                return ResultBean.failedResultOfParamWithMsg("文化程度为空");
            }
            if (vo.getMaritalStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("婚姻状况为空");
            }
            if (StringUtils.isBlank(vo.getMobile())) {
                return ResultBean.failedResultOfParamWithMsg("联系电话为空");
            }
            if (vo.getHealthType() == null) {
                return ResultBean.failedResultOfParamWithMsg("健康状况为空");
            }
            if (vo.getLaborCapacityType() == null) {
                return ResultBean.failedResultOfParamWithMsg("劳动能力为空");
            }
            if (vo.getWorkStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("就业状况为空");
            }
            if (vo.getWorkUnit() == null) {
                return ResultBean.failedResultOfParamWithMsg("工作单位为空");
            }
            if (vo.getMonthIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("月收入为空");
            }
            if (vo.getFamilyIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("家庭月收入为空");
            }
            if (vo.getPerIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("人均月收入为空");
            }
            if (vo.getNatureType() == null) {
                return ResultBean.failedResultOfParamWithMsg("住房性质为空");
            }
            if (vo.getHousingArea() == null) {
                return ResultBean.failedResultOfParamWithMsg("住房面积为空");
            }
            if (StringUtils.isBlank(vo.getFrontCardPic()) || StringUtils.isBlank(vo.getBackCardPic())) {
                return ResultBean.failedResultOfParamWithMsg("身份证照片为空");
            }

            if (StringUtils.isNotBlank(vo.getApplyCode())) {
                Long count3 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply WHERE id IN \n" +
                        "(SELECT data_id FROM  saas_house_apply_flow WHERE apply_code = ? AND TYPE = 1) AND card_number = ?\n", new Object[]{vo.getApplyCode(), vo.getCardNumber()}, Long.class);
                Long count4 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply_cohabit WHERE id IN \n" +
                        "(SELECT data_id FROM  saas_house_apply_flow WHERE apply_code = ? AND TYPE = 2) AND card_number = ?\n", new Object[]{vo.getApplyCode(), vo.getCardNumber()}, Long.class);
                if (count3 + count4 > 0) {
                    return ResultBean.failedResultWithMsg("人员信息重复，请核实后提交");
                }
            }

            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();
            Long enterpriseId = tokenRedisVo.getEnterpriseId();
            Date date = new Date();

            // 查审批流程设置人
            ApprovalProcess approvalProcess = approvalProcessRepository.findByDistrictIdAndStatus(vo.getDistrictId(),
                    1);
            ArrayList<Long> areaIds = new ArrayList<>();
            if (approvalProcess != null) {
                String process = approvalProcess.getApprovalProcess();
                String[] split = process.split(",");
                for (String s : split) {
                    int i = Integer.parseInt(s);
                    if (i == 1) {
                        areaIds.add(vo.getProvinceId());
                    } else if (i == 2) {
                        areaIds.add(vo.getCityId());
                    } else if (i == 3) {
                        areaIds.add(vo.getDistrictId());
                    } else if (i == 4) {
                        areaIds.add(vo.getStreetId());
                    } else if (i == 5) {
                        areaIds.add(vo.getCommunityId());
                    }
                }
            } else {
                areaIds.add(vo.getCommunityId());
                areaIds.add(vo.getStreetId());
                areaIds.add(vo.getDistrictId());
            }

            // 生成资格申请
            Eligible eligible = new Eligible();
            if (StringUtils.isBlank(vo.getApplyCode())) {
                eligible.setApplyCode(KeyWorker.nextId() + "");
            } else {
                eligible.setApplyCode(vo.getApplyCode());
            }
            eligible.setType(type);
            AppUser applyUser = appUserRepository.findByCardNumber(vo.getCardNumber());
            if (applyUser == null) {
                return ResultBean.failedResultWithMsg("申请人用户数据不存在");
            }

            if (type == 1) {// 个人申请
                eligible.setMatchUserId(applyUser.getId());
            } else if (type == 2) {// 单位申请
                eligible.setMatchUserId(applyUser.getId());
                if (enterpriseId != null) {
                    eligible.setOrgId(enterpriseId);
                }
                eligible.setOrgUserName(vo.getOrgUserName());
                eligible.setOrgUserMobile(vo.getOrgUserMobile());
                eligible.setOrgBusinessLicense(vo.getOrgBusinessLicense());
            }
            eligible.setProvinceId(vo.getProvinceId());
            eligible.setCityId(vo.getCityId());
            eligible.setDistrictId(vo.getDistrictId());
            eligible.setStreetId(vo.getStreetId());
            eligible.setCommunityId(vo.getCommunityId());
            List<Long> ids = Arrays.asList(vo.getProvinceId(), vo.getCityId(), vo.getDistrictId(), vo.getStreetId(), vo.getCommunityId());
            List<Area> areas = areaRepository.findByIdIn(ids);
            String province = "";
            String city = "";
            String district = "";
            String street = "";
            String community = "";
            for (Area area : areas) {
                Integer level = area.getLevel();
                String name = area.getName();
                if (level == 1) {
                    province = name;
                } else if (level == 2) {
                    city = name;
                } else if (level == 3) {
                    district = name;
                } else if (level == 4) {
                    street = name;
                } else if (level == 5) {
                    community = name;
                }
            }
            eligible.setApplyArea(province + city + district + street + community);
            eligible.setAttributeType(vo.getAttributeType());
            eligible.setName(vo.getName());// 姓名
            eligible.setEthnic(vo.getEthnic());// 名族
            eligible.setBirthDate(vo.getBirthDate());// 出生日期
            eligible.setCardNumber(vo.getCardNumber());// 身份证号
            eligible.setCardAddress(vo.getCardAddress());// 身份证地址
            eligible.setDomicileProvinceId(vo.getDomicileProvinceId());
            eligible.setDomicileCityId(vo.getDomicileCityId());
            eligible.setDomicileDistrictId(vo.getDomicileDistrictId());
            eligible.setFamilyTiesType(vo.getFamilyTiesType());
            eligible.setCultureType(vo.getCultureType());
            eligible.setMaritalStatus(vo.getMaritalStatus());
            eligible.setMobile(vo.getMobile());
            eligible.setHealthType(vo.getHealthType());
            eligible.setLaborCapacityType(vo.getLaborCapacityType());
            eligible.setWorkStatus(vo.getWorkStatus());
            eligible.setWorkUnit(vo.getWorkUnit());
            eligible.setMonthIncomeAmount(ConvertUtils.yuan2fen(vo.getMonthIncomeAmount()));
            eligible.setFamilyIncomeAmount(ConvertUtils.yuan2fen(vo.getFamilyIncomeAmount()));
            eligible.setPerIncomeAmount(ConvertUtils.yuan2fen(vo.getPerIncomeAmount()));
            eligible.setNatureType(vo.getNatureType());
            eligible.setHousingArea(vo.getHousingArea());
            eligible.setFrontCardPic(vo.getFrontCardPic());
            eligible.setBackCardPic(vo.getBackCardPic());
            eligible.setApplyStatus(EligibleApplyTypeEnum.DRAFT.getValue());
            eligible.setOperationId(userId);
            eligible.setApplyTime(date);
            eligible.setPropertyStatus(vo.getPropertyStatus());
            eligible.setPriorityGroupsStatus(vo.getPriorityGroupsStatus());
            Eligible save = eligibleRepository.save(eligible);

            Map<Integer, List<String>> fileKeys = vo.getFileKeys();
            if (fileKeys != null) {
                for (Integer integer : fileKeys.keySet()) {
                    // 获取fileKey缓存
                    String redis = (String) redisTemplate.opsForHash().get("ELIGIBLE:" + vo.getCardNumber(),
                            integer.toString());
                    List<String> fileKeyList = fileKeys.get(integer);
                    if (!StringUtils.isBlank(redis)) {
                        String[] split = redis.split(",");
                        List<String> redisList = new ArrayList<>(Arrays.asList(split));
                        // 取出缓存中多余的fileKey
                        List<String> differentList = listCompare(redisList, fileKeyList);
                        // 删除Oss中多余的文件
                        for (String str : differentList) {
                            ossService.deleteObject(ossConfig.getOssBucketName(), str);
                        }
                    }
                    // 生成上传文件记录
                    for (String str : fileKeyList) {
                        HouseApplyMaterial material = new HouseApplyMaterial();
                        material.setApplyId(save.getId());
                        material.setMaterialType(integer);
                        String url = ossService.getOssFilePath(str);
                        material.setUrl(url);
                        houseApplyMaterialRepository.save(material);
                    }
                }
                // 删除redis缓存
                redisTemplate.delete("ELIGIBLE:" + vo.getCardNumber());
            }

            // 生成审批流程明细数据
            int sortby = 1;
            int number = 1;
            for (Long areaId : areaIds) {
                ApplyAudit audit = new ApplyAudit();
                audit.setApplyId(save.getId());
                if (approvalProcess != null) {
                    audit.setAuditProcessId(approvalProcess.getId());
                }
                ApprovalProcessUser approvalProcessUser = approvalProcessUserRepository.findByAreaIdAndStatus(areaId,
                        1);
                if (approvalProcessUser == null) {
                    audit.setCurrentAuditId(null);
                } else {
                    audit.setCurrentAuditId(approvalProcessUser.getAuditorUserId());
                }
                if (sortby == 1) {
                    audit.setAuditStatus(1);
                } else {
                    audit.setAuditStatus(0);
                }
                audit.setSortby(sortby++);
                audit.setNumber(number++);
                audit.setOrgAreaId(areaId);
                applyAuditRepository.save(audit);
            }

            // 生成申请资料填写流程
            HouseApplyFlow flow = new HouseApplyFlow();
            String applyCode = eligible.getApplyCode();
            flow.setApplyCode(applyCode);
            flow.setType(1);
            flow.setDataId(save.getId().toString());
            if (StringUtils.isBlank(vo.getApplyCode())) {
                flow.setUpDataId(null);
                flow.setNextDataId(null);
                flow.setNumber(1);
            } else {
                flow.setUpDataId(vo.getUpDataId());
                // 更新上一流程的next_data_id
                houseApplyFlowRepository.updateByDataId(vo.getUpDataId(), save.getId().toString());
                flow.setNextDataId(null);
                flow.setNumber(vo.getNumber() + 1);
            }
            flow.setApplyId(save.getId());
            houseApplyFlowRepository.save(flow);

            EligibleReturnVO returnVO = new EligibleReturnVO();
            returnVO.setApplyCode(eligible.getApplyCode());
            returnVO.setDataId(save.getId().toString());
            returnVO.setNumber(flow.getNumber());

            return ResultBean.successfulResult(returnVO);
        } catch (Exception e) {
            log.error("EligibleService saveEligible Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional
    public ResultBean<Object> updateEligible(String accessToken, EligibleVO vo) {
        try {
            if (vo.getId() == null) {
                return ResultBean.failedResultOfParamWithMsg("id为空");
            }
            if (vo.getAttributeType() == null) {
                return ResultBean.failedResultOfParamWithMsg("人员属性为空");
            }
            if (StringUtils.isBlank(vo.getName()) || StringUtils.isBlank(vo.getEthnic())
                    || StringUtils.isBlank(vo.getBirthDate()) || StringUtils.isBlank(vo.getCardNumber())
                    || StringUtils.isBlank(vo.getCardAddress())) {
                return ResultBean.failedResultOfParamWithMsg("身份证信息为空");
            }
            if (vo.getDomicileProvinceId() == null || vo.getDomicileCityId() == null
                    || vo.getDomicileDistrictId() == null) {
                return ResultBean.failedResultOfParamWithMsg("户籍地为空");
            }
            if (vo.getFamilyTiesType() == null) {
                return ResultBean.failedResultOfParamWithMsg("家庭关系为空");
            }
            if (vo.getCultureType() == null) {
                return ResultBean.failedResultOfParamWithMsg("文化程度为空");
            }
            if (vo.getMaritalStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("婚姻状况为空");
            }
            if (StringUtils.isBlank(vo.getMobile())) {
                return ResultBean.failedResultOfParamWithMsg("联系电话为空");
            }
            if (vo.getHealthType() == null) {
                return ResultBean.failedResultOfParamWithMsg("健康状况为空");
            }
            if (vo.getLaborCapacityType() == null) {
                return ResultBean.failedResultOfParamWithMsg("劳动能力为空");
            }
            if (vo.getWorkStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("就业状况为空");
            }
            if (vo.getWorkUnit() == null) {
                return ResultBean.failedResultOfParamWithMsg("工作单位为空");
            }
            if (vo.getMonthIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("月收入为空");
            }
            if (vo.getFamilyIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("家庭月收入为空");
            }
            if (vo.getPerIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("人均月收入为空");
            }
            if (vo.getNatureType() == null) {
                return ResultBean.failedResultOfParamWithMsg("住房性质为空");
            }
            if (vo.getHousingArea() == null) {
                return ResultBean.failedResultOfParamWithMsg("住房面积为空");
            }
            if (StringUtils.isBlank(vo.getFrontCardPic()) || StringUtils.isBlank(vo.getBackCardPic())) {
                return ResultBean.failedResultOfParamWithMsg("身份证照片为空");
            }

            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();
            Date date = new Date();

            Optional<Eligible> eligibleOpt = eligibleRepository.findById(vo.getId());
            if (!eligibleOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("资格申请不存在");
            }
            Eligible eligible = eligibleOpt.get();
            // 修改资格申请
            AppUser applyUser = appUserRepository.findByCardNumber(vo.getCardNumber());
            if (applyUser == null) {
                return ResultBean.failedResultWithMsg("申请人数据不存在");
            }
            eligible.setMatchUserId(applyUser.getId());
            eligible.setAttributeType(vo.getAttributeType());
            eligible.setName(vo.getName());// 姓名
            eligible.setEthnic(vo.getEthnic());// 名族
            eligible.setBirthDate(vo.getBirthDate());// 出生日期
            eligible.setCardNumber(vo.getCardNumber());// 身份证号
            eligible.setCardAddress(vo.getCardAddress());// 身份证地址
            eligible.setDomicileProvinceId(vo.getDomicileProvinceId());
            eligible.setDomicileCityId(vo.getDomicileCityId());
            eligible.setDomicileDistrictId(vo.getDomicileDistrictId());
            eligible.setFamilyTiesType(vo.getFamilyTiesType());
            eligible.setCultureType(vo.getCultureType());
            eligible.setMaritalStatus(vo.getMaritalStatus());
            eligible.setMobile(vo.getMobile());
            eligible.setHealthType(vo.getHealthType());
            eligible.setLaborCapacityType(vo.getLaborCapacityType());
            eligible.setWorkStatus(vo.getWorkStatus());
            eligible.setWorkUnit(vo.getWorkUnit());
            eligible.setMonthIncomeAmount(ConvertUtils.yuan2fen(vo.getMonthIncomeAmount()));
            eligible.setFamilyIncomeAmount(ConvertUtils.yuan2fen(vo.getFamilyIncomeAmount()));
            eligible.setPerIncomeAmount(ConvertUtils.yuan2fen(vo.getPerIncomeAmount()));
            eligible.setNatureType(vo.getNatureType());
            eligible.setHousingArea(vo.getHousingArea());
            eligible.setFrontCardPic(vo.getFrontCardPic());
            eligible.setBackCardPic(vo.getBackCardPic());
            eligible.setOperationId(userId);
            eligible.setApplyTime(date);
            eligible.setPropertyStatus(vo.getPropertyStatus());
            eligible.setPriorityGroupsStatus(vo.getPriorityGroupsStatus());

            if (eligible.getApplyStatus() == EligibleApplyTypeEnum.BACKOUT.getValue()) {
                //修改资格申请状态
                eligible.setApplyStatus(EligibleApplyTypeEnum.YET_APPROVE.getValue());
                //重新生成待办事项
                List<ApplyAudit> applyAudits = applyAuditRepository.findByApplyId(vo.getId());
                if (applyAudits.isEmpty()) {
                    return ResultBean.failedResultWithMsg("审批流程不存在");
                }
                ApplyAudit applyAudit = applyAudits.get(0);

                if (applyAudit.getCurrentAuditId() != null) {
                    BacklogItem backlogItem = new BacklogItem();
                    backlogItem.setType(BacklogItemTypeEnum.ELIGIBLE_APPROVE.getValue());
                    backlogItem.setTitle(eligible.getName() + "提交的公租房资格申请");
                    backlogItem.setBusinessStatus("待审批");
                    backlogItem.setHandleStatus(0);
                    backlogItem.setOperatorId(eligible.getMatchUserId());
                    backlogItem.setCreateTime(date);
                    BacklogItem save = backlogItemRepository.save(backlogItem);

                    BacklogItemApprove backlogItemApprove = new BacklogItemApprove();
                    backlogItemApprove.setBacklogItemId(save.getId());
                    backlogItemApprove.setApplyId(vo.getId());
                    backlogItemApprove.setApplyAuditId(applyAudit.getId());
                    backlogItemApprove.setUserId(applyAudit.getCurrentAuditId());
                    backlogItemApprove.setStatus(0);
                    backlogItemApproveRepository.save(backlogItemApprove);
                }
            }

            if (eligible.getApplyStatus() == EligibleApplyTypeEnum.NOT_APPROVE.getValue()) {
                eligible.setApplyStatus(EligibleApplyTypeEnum.YET_APPROVE.getValue());
                // 重置审批流程状态
                List<ApplyAudit> applyAudits = applyAuditRepository.findByApplyId(eligible.getId());
                if (applyAudits.isEmpty()) {
                    return ResultBean.failedResultWithMsg("审批流程不存在");
                }
                for (ApplyAudit applyAudit : applyAudits) {
                    if (applyAudit.getSortby() == 1) {
                        applyAudit.setAuditStatus(1);
                    } else {
                        applyAudit.setAuditStatus(0);
                    }
                    applyAudit.setRemark(null);
                    applyAudit.setAuditTime(null);
                }
                applyAuditRepository.saveAll(applyAudits);
                //删除之前待办事项
                List<BacklogItemApprove> approves = backlogItemApproveRepository.findByApplyId(vo.getId());
                if (!approves.isEmpty()) {
                    List<Long> itemIds = approves.stream().map(BacklogItemApprove::getBacklogItemId).distinct().collect(Collectors.toList());
                    backlogItemApproveRepository.deleteByApplyId(vo.getId());
                    backlogItemRepository.deleteByIdIn(itemIds);
                }
                //重新生成待办事项
                ApplyAudit applyAudit = applyAudits.get(0);
                if (applyAudit.getCurrentAuditId() != null) {
                    BacklogItem backlogItem = new BacklogItem();
                    backlogItem.setType(BacklogItemTypeEnum.ELIGIBLE_APPROVE.getValue());
                    backlogItem.setTitle(eligible.getName() + "提交的公租房资格申请");
                    backlogItem.setBusinessStatus("待审批");
                    backlogItem.setHandleStatus(0);
                    backlogItem.setOperatorId(eligible.getMatchUserId());
                    backlogItem.setCreateTime(date);
                    BacklogItem save = backlogItemRepository.save(backlogItem);

                    BacklogItemApprove backlogItemApprove = new BacklogItemApprove();
                    backlogItemApprove.setBacklogItemId(save.getId());
                    backlogItemApprove.setApplyId(vo.getId());
                    backlogItemApprove.setApplyAuditId(applyAudit.getId());
                    backlogItemApprove.setUserId(applyAudit.getCurrentAuditId());
                    backlogItemApprove.setStatus(0);
                    backlogItemApproveRepository.save(backlogItemApprove);
                }
            }
            eligibleRepository.save(eligible);

            Map<Integer, List<String>> fileKeys = vo.getFileKeys();
            if (fileKeys != null) {
                for (Integer integer : fileKeys.keySet()) {
                    List<String> fileKeyList = fileKeys.get(integer);

                    // 获取数据库fileKey
                    List<HouseApplyMaterial> materials = houseApplyMaterialRepository
                            .findByApplyIdAndMaterialType(eligible.getId(), integer);
                    List<String> dataList = new ArrayList<>();
                    for (HouseApplyMaterial material : materials) {
                        String url = material.getUrl();
                        url = url.replace(ossConfig.getBucketUrl(), "");
                        dataList.add(url);
                    }
                    // 取出数据库中多余的fileKey
                    List<String> differentList = listCompare(dataList, fileKeyList);
                    // 删除数据库中多余的文件
                    for (String str : differentList) {
                        ossService.deleteObject(ossConfig.getOssBucketName(), str);
                    }

                    // 获取fileKey缓存
                    String redis = (String) redisTemplate.opsForHash().get("ELIGIBLE:" + vo.getCardNumber(),
                            integer.toString());
                    if (!StringUtils.isBlank(redis)) {
                        String[] split = redis.split(",");
                        List<String> redisList = new ArrayList<>(Arrays.asList(split));
                        // 取出缓存中多余的fileKey
                        List<String> differentList2 = listCompare(redisList, fileKeyList);
                        // 删除Oss中多余的文件
                        for (String str : differentList2) {
                            ossService.deleteObject(ossConfig.getOssBucketName(), str);
                        }
                    }

                    // 删除上传文件记录
                    houseApplyMaterialRepository.deleteByApplyIdAndMaterialType(eligible.getId(), integer);
                    // 重新生成上传文件记录
                    for (String str : fileKeyList) {
                        HouseApplyMaterial material = new HouseApplyMaterial();
                        material.setApplyId(vo.getId());
                        material.setMaterialType(integer);
                        String url = ossService.getOssFilePath(str);
                        material.setUrl(url);
                        houseApplyMaterialRepository.save(material);
                    }
                }

                // 删除redis缓存
                redisTemplate.delete("ELIGIBLE:" + vo.getCardNumber());
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error("EligibleService updateEligible Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<HouseApplyFlowVO> findApplyFlow(String accessToken, String applyCode, String dataId, Integer type) {
        try {
            log.info("EligibleService findApplyFlow, applyCode={},dataId={},type={}", applyCode, dataId, type);
            if (type == null || type == 1) {
                return findApplyFlow2(accessToken, applyCode, dataId);
            } else {
                return findApplyFlow3(accessToken, applyCode, dataId);
            }

        } catch (Exception e) {
            log.error("EligibleService findApplyFlow Exception = {}" + e.getMessage(), e);
        }
        return ResultBean.failedResultOfException();
    }

    public ResultBean<HouseApplyFlowVO> findApplyFlow2(String accessToken, String applyCode, String dataId) {
        try {
            if (StringUtils.isBlank(applyCode)) {
                return ResultBean.failedResultOfParamWithMsg("同批次编号为空");
            }
            if (StringUtils.isBlank(dataId)) {
                return ResultBean.failedResultOfParamWithMsg("数据id为空");
            }

            HouseApplyFlow flow = houseApplyFlowRepository.findByApplyCodeAndDataId(applyCode, dataId);
            HouseApplyFlowVO vo = new HouseApplyFlowVO();
            vo.setApplyCode(flow.getApplyCode());
            vo.setType(flow.getType());
            vo.setDataId(flow.getDataId());
            vo.setUpDataId(flow.getUpDataId());
            vo.setNextDataId(flow.getNextDataId());
            vo.setNumber(flow.getNumber());

            return ResultBean.successfulResult(vo);
        } catch (Exception e) {
            log.error("EligibleService findApplyFlow Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<HouseApplyFlowVO> findApplyFlow3(String accessToken, String applyCode, String dataId) {
        try {
            if (StringUtils.isBlank(applyCode)) {
                return ResultBean.failedResultOfParamWithMsg("同批次编号为空");
            }
            if (StringUtils.isBlank(dataId)) {
                return ResultBean.failedResultOfParamWithMsg("数据id为空");
            }

            HouseApplyFlowOld flow = houseApplyFlowOldRepository.findByApplyCodeAndDataId(applyCode, dataId);
            HouseApplyFlowVO vo = new HouseApplyFlowVO();
            vo.setApplyCode(flow.getApplyCode());
            vo.setType(flow.getType());
            vo.setDataId(flow.getDataId());
            vo.setUpDataId(flow.getUpDataId());
            vo.setNextDataId(flow.getNextDataId());
            vo.setNumber(flow.getNumber());

            return ResultBean.successfulResult(vo);
        } catch (Exception e) {
            log.error("EligibleService findApplyFlow Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<HouseApplyFlowVO> findLastApplyFlow(String accessToken, String applyCode) {
        try {
            if (StringUtils.isBlank(applyCode)) {
                return ResultBean.failedResultOfParamWithMsg("同批次编号为空");
            }

            HouseApplyFlow flow = jdbcTemplate.queryForObject(
                    "SELECT * FROM saas_house_apply_flow f WHERE f.apply_code = ? AND f.next_data_id IS NULL",
                    new BeanPropertyRowMapper<>(HouseApplyFlow.class), applyCode);

            HouseApplyFlowVO vo = new HouseApplyFlowVO();
            vo.setApplyCode(flow.getApplyCode());
            vo.setType(flow.getType());
            vo.setDataId(flow.getDataId());
            vo.setUpDataId(flow.getUpDataId());
            vo.setNextDataId(flow.getNextDataId());
            vo.setNumber(flow.getNumber());

            return ResultBean.successfulResult(vo);
        } catch (Exception e) {
            log.error("EligibleService findApplyFlow Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<HouseApplyFlowVO> findLastApplyFlow2(String accessToken, Long applyId) {
        try {
            if (applyId == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id为空");
            }

            HouseApplyFlow flow = jdbcTemplate.queryForObject(
                    "SELECT * FROM saas_house_apply_flow WHERE apply_id = ? ORDER BY id DESC LIMIT 1",
                    new BeanPropertyRowMapper<>(HouseApplyFlow.class), applyId);

            HouseApplyFlowVO vo = new HouseApplyFlowVO();
            vo.setApplyCode(flow.getApplyCode());
            vo.setType(flow.getType());
            vo.setDataId(flow.getDataId());
            vo.setUpDataId(flow.getUpDataId());
            vo.setNextDataId(flow.getNextDataId());
            vo.setNumber(flow.getNumber());

            return ResultBean.successfulResult(vo);
        } catch (Exception e) {
            log.error("EligibleService findApplyFlow2 Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional
    public ResultBean<EligibleReturnVO> saveCohabit(String accessToken, CohabitVO vo) {
        try {
            log.info("EligibleService saveCohabit, vo={}", JSON.toJSONString(vo));
            if (vo.getApplyId() == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id为空");
            }
            if (StringUtils.isBlank(vo.getApplyCode())) {
                return ResultBean.failedResultOfParamWithMsg("同批次编号为空");
            }
            if (StringUtils.isBlank(vo.getUpDataId())) {
                return ResultBean.failedResultOfParamWithMsg("上一个数据id为空");
            }
            if (vo.getNumber() == null) {
                return ResultBean.failedResultOfParamWithMsg("序号为空");
            }
            if (StringUtils.isBlank(vo.getName()) || StringUtils.isBlank(vo.getEthnic())
                    || StringUtils.isBlank(vo.getBirthDate()) || StringUtils.isBlank(vo.getCardNumber())
                    || StringUtils.isBlank(vo.getCardAddress())) {
                return ResultBean.failedResultOfParamWithMsg("身份证信息为空");
            }
            if (vo.getDomicileProvinceId() == null || vo.getDomicileCityId() == null
                    || vo.getDomicileDistrictId() == null) {
                return ResultBean.failedResultOfParamWithMsg("户籍地为空");
            }
            if (vo.getFamilyTiesType() == null) {
                return ResultBean.failedResultOfParamWithMsg("家庭关系为空");
            }
            if (vo.getCultureType() == null) {
                return ResultBean.failedResultOfParamWithMsg("文化程度为空");
            }
            if (vo.getMaritalStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("婚姻状况为空");
            }
            if (StringUtils.isBlank(vo.getMobile())) {
                return ResultBean.failedResultOfParamWithMsg("联系电话为空");
            }
            if (vo.getHealthType() == null) {
                return ResultBean.failedResultOfParamWithMsg("健康状况为空");
            }
            if (vo.getLaborCapacityType() == null) {
                return ResultBean.failedResultOfParamWithMsg("劳动能力为空");
            }
            if (vo.getWorkStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("就业状况为空");
            }
            if (vo.getWorkStatus() != 0 && StringUtils.isBlank(vo.getWorkUnit())) {
                return ResultBean.failedResultOfParamWithMsg("工作单位为空");
            }
            if (vo.getMonthIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("月收入为空");
            }
            /*if (StringUtils.isBlank(vo.getFrontCardPic()) || StringUtils.isBlank(vo.getBackCardPic())) {
                return ResultBean.failedResultOfParamWithMsg("身份证照片为空");
            }*/

            Optional<Eligible> eligibleOpt = eligibleRepository.findById(vo.getApplyId());
            if (!eligibleOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("资格申请不存在");
            }
            Eligible eligible = eligibleOpt.get();

            if (eligible.getApplyStatus() == 4 || eligible.getApplyStatus() == 6) {
                Long count3 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply WHERE id = ? AND card_number = ?",
                        new Object[]{vo.getApplyId(), vo.getCardNumber()}, Long.class);
                Long count4 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply_cohabit WHERE apply_id = ? AND card_number = ?",
                        new Object[]{vo.getApplyId(), vo.getCardNumber()}, Long.class);
                if (count3 + count4 > 0) {
                    return ResultBean.failedResultWithMsg("人员信息重复，请核实后提交");
                }
            } else {
                Long count3 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply WHERE id IN \n" +
                        "(SELECT data_id FROM  saas_house_apply_flow WHERE apply_code = ? AND TYPE = 1) AND card_number = ?\n", new Object[]{vo.getApplyCode(), vo.getCardNumber()}, Long.class);
                Long count4 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply_cohabit WHERE id IN \n" +
                        "(SELECT data_id FROM  saas_house_apply_flow WHERE apply_code = ? AND TYPE = 2) AND card_number = ?\n", new Object[]{vo.getApplyCode(), vo.getCardNumber()}, Long.class);
                if (count3 + count4 > 0) {
                    return ResultBean.failedResultWithMsg("人员信息重复，请核实后提交");
                }
            }

            //验证同住人是否重复申请
            Long count1 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply` a \n" +
                    "where a.apply_status in (1,2,3,10) and a.card_number = ?", new Object[]{vo.getCardNumber()}, Long.class);
            Long count2 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply_cohabit` c left join `saas_house_eligible_apply` a on c.apply_id = a.id\n" +
                    "where a.apply_status in (1,2,3,10) and c.card_number = ?", new Object[]{vo.getCardNumber()}, Long.class);
            if (count1 + count2 > 0) {
                return ResultBean.failedResultWithMsg("同住人信息已有公租房申请记录，请核实后提交");
            }

            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();
            Date date = new Date();

            Cohabit cohabit = new Cohabit();
            cohabit.setId(KeyWorker.nextId() + "");
            cohabit.setApplyId(vo.getApplyId());
            cohabit.setName(vo.getName());
            cohabit.setEthnic(vo.getEthnic());
            cohabit.setBirthDate(vo.getBirthDate());
            cohabit.setCardNumber(vo.getCardNumber());
            cohabit.setCardAddress(vo.getCardAddress());
            cohabit.setDomicileProvinceId(vo.getDomicileProvinceId());
            cohabit.setDomicileCityId(vo.getDomicileCityId());
            cohabit.setDomicileDistrictId(vo.getDomicileDistrictId());
            cohabit.setFamilyTiesType(vo.getFamilyTiesType());
            cohabit.setCultureType(vo.getCultureType());
            cohabit.setMaritalStatus(vo.getMaritalStatus());
            cohabit.setMobile(vo.getMobile());
            cohabit.setHealthType(vo.getHealthType());
            cohabit.setLaborCapacityType(vo.getLaborCapacityType());
            cohabit.setWorkStatus(vo.getWorkStatus());
            if (vo.getWorkStatus() != 0) {
                cohabit.setWorkUnit(vo.getWorkUnit());
            }
            cohabit.setMonthIncomeAmount(ConvertUtils.yuan2fen(vo.getMonthIncomeAmount()));
            cohabit.setFrontCardPic(vo.getFrontCardPic());
            cohabit.setBackCardPic(vo.getBackCardPic());
            cohabit.setStatus(1);
            cohabit.setOperationId(userId);
            cohabit.setApplyTime(date);
            cohabit.setFacePic(vo.getFacePic());
            Cohabit save = cohabitRepository.save(cohabit);

            //编辑资格申请新增同住人，申请状态与待办事项处理
            ResultBean<Object> resultBean = updateApplyData(eligible, date);
            if (resultBean != null) {
                return ResultBean.failedResultWithMsg(resultBean.getMsg());
            }

            Map<Integer, List<String>> fileKeys = vo.getFileKeys();
            if (fileKeys != null) {
                for (Integer integer : fileKeys.keySet()) {
                    // 获取fileKey缓存
                    String redis = (String) redisTemplate.opsForHash().get("COHABIT:" + vo.getCardNumber(),
                            integer.toString());
                    List<String> fileKeyList = fileKeys.get(integer);
                    if (!StringUtils.isBlank(redis)) {
                        String[] split = redis.split(",");
                        List<String> redisList = new ArrayList<>(Arrays.asList(split));
                        // 取出缓存中多余的fileKey
                        List<String> differentList = listCompare(redisList, fileKeyList);
                        // 删除Oss中多余的文件
                        for (String str : differentList) {
                            ossService.deleteObject(ossConfig.getOssBucketName(), str);
                        }
                    }
                    // 生成上传文件记录
                    for (String str : fileKeyList) {
                        HouseCohabitMaterial material = new HouseCohabitMaterial();
                        material.setApplyId(vo.getApplyId());
                        material.setCohabitId(save.getId());
                        material.setMaterialType(integer);
                        String url = ossService.getOssFilePath(str);
                        material.setUrl(url);
                        houseCohabitMaterialRepository.save(material);
                    }
                }
                // 删除redis缓存
                redisTemplate.delete("COHABIT:" + vo.getCardNumber());
            }

            // 生成申请资料填写流程
            HouseApplyFlow flow = new HouseApplyFlow();
            flow.setApplyCode(vo.getApplyCode());
            flow.setType(2);
            flow.setDataId(save.getId());
            flow.setUpDataId(vo.getUpDataId());
            // 更新上一流程的next_data_id
            houseApplyFlowRepository.updateByDataId(vo.getUpDataId(), save.getId());
            flow.setNextDataId(null);
            flow.setNumber(vo.getNumber() + 1);
            flow.setApplyId(vo.getApplyId());
            houseApplyFlowRepository.save(flow);

            EligibleReturnVO returnVO = new EligibleReturnVO();
            returnVO.setApplyCode(vo.getApplyCode());
            returnVO.setDataId(save.getId());
            returnVO.setNumber(flow.getNumber());

            return ResultBean.successfulResult(returnVO);
        } catch (Exception e) {
            log.error("EligibleService saveCohabit Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional
    public ResultBean<Object> updateCohabit(String accessToken, CohabitVO vo) {
        try {
            log.info("EligibleService updateCohabit, vo={}", JSON.toJSONString(vo));
            if (StringUtils.isBlank(vo.getId())) {
                return ResultBean.failedResultOfParamWithMsg("id为空");
            }
            if (StringUtils.isBlank(vo.getName()) || StringUtils.isBlank(vo.getEthnic())
                    || StringUtils.isBlank(vo.getBirthDate()) || StringUtils.isBlank(vo.getCardNumber())
                    || StringUtils.isBlank(vo.getCardAddress())) {
                return ResultBean.failedResultOfParamWithMsg("身份证信息为空");
            }
            if (vo.getDomicileProvinceId() == null || vo.getDomicileCityId() == null
                    || vo.getDomicileDistrictId() == null) {
                return ResultBean.failedResultOfParamWithMsg("户籍地为空");
            }
            if (vo.getFamilyTiesType() == null) {
                return ResultBean.failedResultOfParamWithMsg("家庭关系为空");
            }
            if (vo.getCultureType() == null) {
                return ResultBean.failedResultOfParamWithMsg("文化程度为空");
            }
            if (vo.getMaritalStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("婚姻状况为空");
            }
            if (StringUtils.isBlank(vo.getMobile())) {
                return ResultBean.failedResultOfParamWithMsg("联系电话为空");
            }
            if (vo.getHealthType() == null) {
                return ResultBean.failedResultOfParamWithMsg("健康状况为空");
            }
            if (vo.getLaborCapacityType() == null) {
                return ResultBean.failedResultOfParamWithMsg("劳动能力为空");
            }
            if (vo.getWorkStatus() == null) {
                return ResultBean.failedResultOfParamWithMsg("就业状况为空");
            }
            if (vo.getWorkStatus() != 0 && StringUtils.isBlank(vo.getWorkUnit())) {
                return ResultBean.failedResultOfParamWithMsg("工作单位为空");
            }
            if (vo.getMonthIncomeAmount() == null) {
                return ResultBean.failedResultOfParamWithMsg("月收入为空");
            }
            /*if (StringUtils.isBlank(vo.getFrontCardPic()) || StringUtils.isBlank(vo.getBackCardPic())) {
                return ResultBean.failedResultOfParamWithMsg("身份证照片为空");
            }*/

            Optional<Cohabit> cohabitOpt = cohabitRepository.findById(vo.getId());
            if (!cohabitOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("同住人不存在");
            }
            Cohabit cohabit = cohabitOpt.get();

            Optional<Eligible> eligibleOpt = eligibleRepository.findById(vo.getApplyId());
            if (!eligibleOpt.isPresent()) {
                return ResultBean.failedResultOfParamWithMsg("资格申请不存在");
            }
            Eligible eligible = eligibleOpt.get();

            if (!cohabit.getCardNumber().equals(vo.getCardNumber())) {
                if (eligible.getApplyStatus() == 4 || eligible.getApplyStatus() == 6) {
                    Long count3 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply WHERE id = ? AND card_number = ?",
                            new Object[]{vo.getApplyId(), vo.getCardNumber()}, Long.class);
                    Long count4 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply_cohabit WHERE apply_id = ? AND card_number = ?",
                            new Object[]{vo.getApplyId(), vo.getCardNumber()}, Long.class);
                    if (count3 + count4 > 0) {
                        return ResultBean.failedResultWithMsg("人员信息重复，请核实后提交");
                    }
                } else {
                    Long count3 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply WHERE id IN \n" +
                            "(SELECT data_id FROM  saas_house_apply_flow WHERE apply_code = ? AND TYPE = 1) AND card_number = ?\n", new Object[]{vo.getApplyCode(), vo.getCardNumber()}, Long.class);
                    Long count4 = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply_cohabit WHERE id IN \n" +
                            "(SELECT data_id FROM  saas_house_apply_flow WHERE apply_code = ? AND TYPE = 2) AND card_number = ?\n", new Object[]{vo.getApplyCode(), vo.getCardNumber()}, Long.class);
                    if (count3 + count4 > 0) {
                        return ResultBean.failedResultWithMsg("人员信息重复，请核实后提交");
                    }
                }

                //验证同住人是否重复申请
                Long count1 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply` a \n" +
                        "where a.apply_status in (1,2,3,10) and a.card_number = ?", new Object[]{vo.getCardNumber()}, Long.class);
                Long count2 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply_cohabit` c left join `saas_house_eligible_apply` a on c.apply_id = a.id\n" +
                        "where a.apply_status in (1,2,3,10) and c.card_number = ?", new Object[]{vo.getCardNumber()}, Long.class);
                if (count1 + count2 > 0) {
                    return ResultBean.failedResultWithMsg("同住人信息已有公租房申请记录，请核实后提交");
                }
            }

            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();
            Date date = new Date();

            cohabit.setName(vo.getName());
            cohabit.setEthnic(vo.getEthnic());
            cohabit.setBirthDate(vo.getBirthDate());
            cohabit.setCardNumber(vo.getCardNumber());
            cohabit.setCardAddress(vo.getCardAddress());
            cohabit.setDomicileProvinceId(vo.getDomicileProvinceId());
            cohabit.setDomicileCityId(vo.getDomicileCityId());
            cohabit.setDomicileDistrictId(vo.getDomicileDistrictId());
            cohabit.setFamilyTiesType(vo.getFamilyTiesType());
            cohabit.setCultureType(vo.getCultureType());
            cohabit.setMaritalStatus(vo.getMaritalStatus());
            cohabit.setMobile(vo.getMobile());
            cohabit.setHealthType(vo.getHealthType());
            cohabit.setLaborCapacityType(vo.getLaborCapacityType());
            cohabit.setWorkStatus(vo.getWorkStatus());
            if (vo.getWorkStatus() != 0) {
                cohabit.setWorkUnit(vo.getWorkUnit());
            }
            cohabit.setMonthIncomeAmount(ConvertUtils.yuan2fen(vo.getMonthIncomeAmount()));
            cohabit.setFrontCardPic(vo.getFrontCardPic());
            cohabit.setBackCardPic(vo.getBackCardPic());
            cohabit.setOperationId(userId);
            cohabit.setApplyTime(date);
            cohabit.setFacePic(vo.getFacePic());
            cohabitRepository.save(cohabit);

            //编辑资格申请修改同住人，申请状态与待办事项处理
            ResultBean<Object> resultBean = updateApplyData(eligible, date);
            if (resultBean != null) {
                return ResultBean.failedResultWithMsg(resultBean.getMsg());
            }

            Map<Integer, List<String>> fileKeys = vo.getFileKeys();
            if (fileKeys != null) {
                for (Integer integer : fileKeys.keySet()) {
                    List<String> fileKeyList = fileKeys.get(integer);

                    // 获取数据库fileKey
                    List<HouseCohabitMaterial> materials = houseCohabitMaterialRepository
                            .findByCohabitIdAndMaterialType(cohabit.getId(), integer);
                    List<String> dataList = new ArrayList<>();
                    for (HouseCohabitMaterial material : materials) {
                        String url = material.getUrl();
                        url = url.replace(ossConfig.getBucketUrl(), "");
                        dataList.add(url);
                    }
                    // 取出数据库中多余的fileKey
                    List<String> differentList = listCompare(dataList, fileKeyList);
                    // 删除数据库中多余的文件
                    for (String str : differentList) {
                        ossService.deleteObject(ossConfig.getOssBucketName(), str);
                    }

                    // 获取fileKey缓存
                    String redis = (String) redisTemplate.opsForHash().get("COHABIT:" + vo.getCardNumber(),
                            integer.toString());
                    if (!StringUtils.isBlank(redis)) {
                        String[] split = redis.split(",");
                        List<String> redisList = new ArrayList<>(Arrays.asList(split));
                        // 取出缓存中多余的fileKey
                        List<String> differentList2 = listCompare(redisList, fileKeyList);
                        // 删除Oss中多余的文件
                        for (String str : differentList2) {
                            ossService.deleteObject(ossConfig.getOssBucketName(), str);
                        }
                    }

                    // 删除上传文件记录
                    houseCohabitMaterialRepository.deleteByCohabitIdAndMaterialType(cohabit.getId(), integer);
                    // 重新生成上传文件记录
                    for (String str : fileKeyList) {
                        HouseCohabitMaterial material = new HouseCohabitMaterial();
                        material.setApplyId(cohabit.getApplyId());
                        material.setCohabitId(vo.getId());
                        material.setMaterialType(integer);
                        String url = ossService.getOssFilePath(str);
                        material.setUrl(url);
                        houseCohabitMaterialRepository.save(material);
                    }
                }

                // 删除redis缓存
                redisTemplate.delete("COHABIT:" + vo.getCardNumber());
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error("EligibleService saveCohabit Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional
    public ResultBean<Object> deleteCohabit(String accessToken, CohabitVO vo) {
        try {
            log.info("EligibleService deleteCohabit, vo={}", JSON.toJSONString(vo));
            if (StringUtils.isBlank(vo.getId())) {
                return ResultBean.failedResultOfParamWithMsg("id为空");
            }

            Optional<Cohabit> cohabitOpt = cohabitRepository.findById(vo.getId());
            if (!cohabitOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("同住人不存在");
            }

            HouseApplyFlow flow = houseApplyFlowRepository.findByDataId(vo.getId());
            String upDataId = flow.getUpDataId();
            String nextDataId = flow.getNextDataId();
            //更新上一流程
            houseApplyFlowRepository.updateByDataId(upDataId, nextDataId);
            //更新下一流程
            if (StringUtils.isNotBlank(nextDataId)) {
                houseApplyFlowRepository.updateNextDataIdByDataId(nextDataId, upDataId);
            }
            //删除流程
            houseApplyFlowRepository.deleteByDataId(vo.getId());

            cohabitRepository.deleteById(vo.getId());
            houseCohabitMaterialRepository.deleteByCohabitId(vo.getId());

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error("EligibleService deleteCohabit Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 资格申请列表,实现资格申请列表的查询
     *
     * @param accessToken 权限鉴定
     * @param status      1未审核 2审核中 3已审核 4审核不通过 6已撤销 9已过期 10轮候配租 11待配租 12已完成
     * @param pageNumber  当前页
     * @param pageSize    页数
     * @return
     */
    public ResultBean<ApiData<EligibleListVO>> eligibleList(String accessToken, String name, Integer type, String applyArea, Integer status,
                                                            Integer pageNumber, Integer pageSize) {
        //设置返回值
        ResultBean<ApiData<EligibleListVO>> resultBean = new ResultBean<>();
        resultBean.setCode("10000");
        resultBean.setMsg("10000");
        //设置返回数据
        ApiData<EligibleListVO> apiData = new ApiData<>();
        resultBean.setResultData(apiData);
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取用户ID
            String userId = tokenRedisVo.getId();
            //获取企业ID
            Long enterpriseId = tokenRedisVo.getEnterpriseId();
            //获取用户登录标签
            Integer loginType = tokenRedisVo.getLoginType();

            String cardNumber = null;
            //查询用户数据
            AppUser user = appUserRepository.findByIdOrEnterpriseUserId(userId, userId);
            //如果用户数据不为空，获取用户身份信息
            if (user != null) {
                cardNumber = user.getCardNumber();
            }
            //字符串拼接
            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where 1 = 1");
            //判断是企业用户还是普通用户
            if (loginType == 1) {
                where.append(" and (a.org_id = ? OR a.card_number = ?)");
                args.add(enterpriseId);
                args.add(cardNumber);
            } else if (loginType == 2) {
                where.append(" and a.card_number = ?");
                args.add(cardNumber);
            }
            where.append(" and a.apply_status != 0");
            //根据前端输入的名字查询数据
            if (StringUtils.isNotBlank(name)) {
                where.append(" and a.name like ?");
                args.add("%" + name + "%");
            }
            if (type != null) {
                where.append(" and a.type = ?");
                args.add(type);
            }
            if (StringUtils.isNotBlank(applyArea)) {
                where.append(" and a.apply_area like ?");
                args.add("%" + applyArea + "%");
            }
            //根据前端传过来不同的状态，查询出不用的数据
            if (status != null) {
                if (status == 11) {
                    where.append(" and a.match_status = 1");
                } else if (status == 12) {
                    where.append(" and a.match_status = 2");
                } else if (status == 13) {
                    where.append(" and a.match_status = 3");
                } else {
                    where.append(" and a.apply_status = ?");
                    args.add(status);
                }
            }

            // 总记录数
            Long total = jdbcTemplate.queryForObject("SELECT count(1) FROM `saas_house_eligible_apply` a" + where,
                    args.toArray(), Long.class);
            if (total == 0) {
                return resultBean;
            }
            //设置当前页
            args.add(pageSize);
            //设置页数
            args.add(pageNumber * pageSize);
            //查询出对应用户的数据
            List<EligibleListVO> list = jdbcTemplate.query(
                    "SELECT a.id,a.match_user_id as matchUserId,a.name,a.type,a.apply_status as applyStatus,a.match_status as matchStatus,\n"
                            + "a.province_id as provinceId,a.city_id as cityId,a.district_id as districtId,a.street_id as streetId,a.community_id as communityId,\n"
                            + "a.apply_time as applyTime FROM `saas_house_eligible_apply` a " + where + ELIGIBLE_ORDER + SQL_PAGE,
                    new BeanPropertyRowMapper<>(EligibleListVO.class), args.toArray());

            // 查询申请人名称
            List<String> ids = list.stream().filter(vo -> vo.getMatchUserId() != null)
                    .map(EligibleListVO::getMatchUserId).distinct().collect(Collectors.toList());
            if (!ids.isEmpty()) {
                // 批量查询用户, 根据普通用户id与企业用户id
                List<AppUser> appUsers = appUserRepository.findByIdOrEnterpriseIn(ids, ids);
                for (AppUser appUser : appUsers) {
                    for (EligibleListVO vo : list) {
                        if (vo.getMatchUserId() != null && (vo.getMatchUserId().equals(appUser.getId())
                                || vo.getMatchUserId().equals(appUser.getEnterpriseUserId()))) {
                            vo.setMatchUserName(appUser.getName());
                        }
                    }
                }
            }

            // 查询区域名称
            //查询出对应省、市、区、街道、社区的数据，并存储起来
            List<Long> areaIds = new ArrayList<>();
            List<Long> provinceIds = list.stream().filter(vo -> vo.getProvinceId() != null).map(EligibleListVO::getProvinceId).distinct().collect(Collectors.toList());
            List<Long> cityIds = list.stream().filter(vo -> vo.getCityId() != null).map(EligibleListVO::getCityId).distinct().collect(Collectors.toList());
            List<Long> districtIds = list.stream().filter(vo -> vo.getDistrictId() != null).map(EligibleListVO::getDistrictId).distinct().collect(Collectors.toList());
            List<Long> streetIds = list.stream().filter(vo -> vo.getStreetId() != null).map(EligibleListVO::getStreetId).distinct().collect(Collectors.toList());
            List<Long> communityIds = list.stream().filter(vo -> vo.getCommunityId() != null).map(EligibleListVO::getCommunityId).distinct().collect(Collectors.toList());
            areaIds.addAll(provinceIds);
            areaIds.addAll(cityIds);
            areaIds.addAll(districtIds);
            areaIds.addAll(streetIds);
            areaIds.addAll(communityIds);
            if (!ids.isEmpty()) {
                Map<Long, String> map = areaRepository.findByIdIn(areaIds).stream().collect(Collectors.toMap(Area::getId, Area::getName));
                if (!map.isEmpty()) {
                    for (EligibleListVO vo : list) {
                        vo.setProvince(map.get(vo.getProvinceId()));
                        vo.setCity(map.get(vo.getCityId()));
                        vo.setDistrict(map.get(vo.getDistrictId()));
                        vo.setStreet(map.get(vo.getStreetId()));
                        vo.setCommunity(map.get(vo.getCommunityId()));
                    }
                }
            }
            //遍历设置申请时间
            for (EligibleListVO vo : list) {
                vo.setApplyTime(DateUtils.format(vo.getApplyTime(), DateUtils.FORMAT_DATETIME_14,
                        DateUtils.FORMAT_DATETIME_14));
            }
            //存储数据
            apiData.setData(list);
            apiData.setTotal(total);
            //把数据响应给前端页面
            resultBean.setResultData(apiData);
        } catch (Exception e) {
            //异常记录日志
            log.error("EligibleService eligibleList Exception = {}" + e.getMessage(), e);
            //提示用户系统异常
            resultBean.setCode("10001");
            resultBean.setMsg("10001");
        }
        //把数据响应给前端页面
        resultBean.setResultData(apiData);
        return resultBean;
    }

    private EligibleListVO convert(Eligible eligible) {
        EligibleListVO vo = new EligibleListVO();
        vo.setId(eligible.getId());
        vo.setMatchUserId(eligible.getMatchUserId());
        vo.setApplyStatus(eligible.getApplyStatus());
        vo.setMatchStatus(eligible.getMatchStatus());
        vo.setCommunityId(eligible.getCommunityId());
        vo.setName(eligible.getName());
        vo.setApplyTime(DateUtils.format(eligible.getApplyTime(), DateUtils.FORMAT_DATETIME_14));
        return vo;
    }

    /*public ResultBean<FindFlowVO<ApplyAuditVO>> findFlow(String accessToken, Long id, Long backlogItemId) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            FindFlowVO<ApplyAuditVO> findFlowVO = new FindFlowVO<>();
            Long applyId = 0L;
            if (id != null) {
                applyId = id;
            }
            if (backlogItemId != null) {
                BacklogItemApprove backlogItemApprove = backlogItemApproveRepository.findByBacklogItemId(backlogItemId);
                applyId = backlogItemApprove.getApplyId();
            }

            Optional<Eligible> eligibleOpt = eligibleRepository.findById(applyId);
            if (!eligibleOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("资格申请不存在");
            }
            Eligible eligible = eligibleOpt.get();

            List<ApplyAudit> audits = applyAuditRepository.findByApplyId(applyId);// 流程明细表
            if (audits == null || audits.isEmpty()) {
                return ResultBean.failedResultWithMsg("审批流程不存在");
            }

            // 更新流程审批人数据
            for (ApplyAudit audit : audits) {
                String currentAuditId = audit.getCurrentAuditId();
                if (StringUtils.isBlank(currentAuditId)) {
                    Long orgAreaId = audit.getOrgAreaId();
                    ApprovalProcessUser approvalProcessUser = approvalProcessUserRepository
                            .findByAreaIdAndStatus(orgAreaId, 1);
                    if (approvalProcessUser != null) {
                        audit.setCurrentAuditId(approvalProcessUser.getAuditorUserId());
                        applyAuditRepository.save(audit);
                    }
                }
            }

            List<ApplyAuditVO> list = new ArrayList<>();
            for (ApplyAudit audit : audits) {
                ApplyAuditVO vo = new ApplyAuditVO();
                vo.setId(audit.getId());
                vo.setApplyId(audit.getApplyId());
                vo.setAuditProcessId(audit.getAuditProcessId());
                String currentAuditId = audit.getCurrentAuditId();
                vo.setCurrentAuditId(currentAuditId);
                if (StringUtils.isNotBlank(currentAuditId)) {
                    User user = userRepository.findUserById(currentAuditId);
                    vo.setCurrentAuditName(user.getName());
                    // 查询审批人所属企业名称
                    String deptName = userService.findUserEnterpriseName(user.getId());
                    vo.setDeptName(deptName);
                } else {
                    vo.setCurrentAuditName("待设置");
                }
                vo.setAuditStatus(audit.getAuditStatus());
                vo.setRemark(audit.getRemark());
                vo.setAuditTime(audit.getAuditTime() == null ? ""
                        : DateUtils.format(audit.getAuditTime(), DateUtils.FORMAT_DATETIME_14));
                list.add(vo);
            }

            findFlowVO.setApplyUser(eligible.getName());
            findFlowVO.setApplyTime(DateUtils.format(eligible.getApplyTime(), DateUtils.FORMAT_DATETIME_14));
            findFlowVO.setApplyId(applyId);
            findFlowVO.setApplyStatus(eligible.getApplyStatus());
            findFlowVO.setData(list);

            return ResultBean.successfulResult(findFlowVO);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }*/

    public ResultBean<FindFlowVO<ApplyAuditVO>> findFlow(String accessToken, Long id, Long backlogItemId, Integer type) {
        try {
        	log.info("findFlow, id={}, backlogItemId={}, type={}", id, backlogItemId, type);
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            if (id != null) {
                if (type == null || type == 1) {
                    FindFlowVO<ApplyAuditVO> findFlowVO = new FindFlowVO<>();
                    Long applyId = id;

                    Optional<Eligible> eligibleOpt = eligibleRepository.findById(applyId);
                    if (!eligibleOpt.isPresent()) {
                        return ResultBean.failedResultWithMsg("资格申请不存在");
                    }
                    Eligible eligible = eligibleOpt.get();

                    List<ApplyAudit> audits = applyAuditRepository.findByApplyId(applyId);// 流程明细表
                    if (audits == null || audits.isEmpty()) {
                        return ResultBean.failedResultWithMsg("审批流程不存在");
                    }

                    // 更新流程审批人数据
                    for (ApplyAudit audit : audits) {
                        String currentAuditId = audit.getCurrentAuditId();
                        if (StringUtils.isBlank(currentAuditId)) {
                            Long orgAreaId = audit.getOrgAreaId();
                            ApprovalProcessUser approvalProcessUser = approvalProcessUserRepository.findByAreaIdAndStatus(orgAreaId, 1);
                            if (approvalProcessUser != null) {
                                audit.setCurrentAuditId(approvalProcessUser.getAuditorUserId());
                                applyAuditRepository.save(audit);
                            }
                        }
                    }

                    List<ApplyAuditVO> list = new ArrayList<>();
                    for (ApplyAudit audit : audits) {
                        ApplyAuditVO vo = new ApplyAuditVO();
                        vo.setId(audit.getId());
                        vo.setApplyId(audit.getApplyId());
                        vo.setAuditProcessId(audit.getAuditProcessId());
                        String currentAuditId = audit.getCurrentAuditId();
                        vo.setCurrentAuditId(currentAuditId);
                        if (StringUtils.isNotBlank(currentAuditId)) {
                            User user = userRepository.findUserById(currentAuditId);
                            vo.setCurrentAuditName(user.getName());
                            // 查询审批人所属企业名称
                            String deptName = userService.findUserEnterpriseName(user.getId());
                            vo.setDeptName(deptName);
                        } else {
                            vo.setCurrentAuditName("待设置");
                        }
                        vo.setAuditStatus(audit.getAuditStatus());
                        vo.setRemark(audit.getRemark());
                        vo.setAuditTime(audit.getAuditTime() == null ? ""
                                : DateUtils.format(audit.getAuditTime(), DateUtils.FORMAT_DATETIME_14));
                        list.add(vo);
                    }

                    findFlowVO.setApplyUser(eligible.getName());
                    findFlowVO.setApplyTime(DateUtils.format(eligible.getApplyTime(), DateUtils.FORMAT_DATETIME_14));
                    findFlowVO.setApplyId(applyId);
                    findFlowVO.setApplyStatus(eligible.getApplyStatus());
                    findFlowVO.setData(list);

                    return ResultBean.successfulResult(findFlowVO);
                } else {
                    FindFlowVO<ApplyAuditVO> findFlowVO = new FindFlowVO<>();
                    Long applyId = id;

                    Optional<EligibleOld> eligibleOpt = eligibleOldRepository.findById(applyId);
                    if (!eligibleOpt.isPresent()) {
                        return ResultBean.failedResultWithMsg("资格申请不存在");
                    }
                    EligibleOld eligible = eligibleOpt.get();

                    List<ApplyAuditOld> audits = applyAuditOldRepository.findByApplyId(applyId);// 流程明细表
                    if (audits == null || audits.isEmpty()) {
                        return ResultBean.failedResultWithMsg("审批流程不存在");
                    }

                    List<ApplyAuditVO> list = new ArrayList<>();
                    for (ApplyAuditOld audit : audits) {
                        ApplyAuditVO vo = new ApplyAuditVO();
                        vo.setId(audit.getId());
                        vo.setApplyId(audit.getApplyId());
                        vo.setAuditProcessId(audit.getAuditProcessId());
                        String currentAuditId = audit.getCurrentAuditId();
                        vo.setCurrentAuditId(currentAuditId);
                        if (StringUtils.isNotBlank(currentAuditId)) {
                            User user = userRepository.findUserById(currentAuditId);
                            vo.setCurrentAuditName(user.getName());
                            // 查询审批人所属企业名称
                            String deptName = userService.findUserEnterpriseName(user.getId());
                            vo.setDeptName(deptName);
                        } else {
                            vo.setCurrentAuditName("待设置");
                        }
                        vo.setAuditStatus(audit.getAuditStatus());
                        vo.setRemark(audit.getRemark());
                        vo.setAuditTime(audit.getAuditTime() == null ? "" : DateUtils.format(audit.getAuditTime(), DateUtils.FORMAT_DATETIME_14));
                        list.add(vo);
                    }

                    findFlowVO.setApplyUser(eligible.getName());
                    findFlowVO.setApplyTime(DateUtils.format(eligible.getApplyTime(), DateUtils.FORMAT_DATETIME_14));
                    findFlowVO.setApplyId(applyId);
                    findFlowVO.setApplyStatus(eligible.getApplyStatus());
                    findFlowVO.setData(list);

                    return ResultBean.successfulResult(findFlowVO);
                }
            }

            if (backlogItemId != null) {
                BacklogItemApprove backlogItemApprove = backlogItemApproveRepository.findByBacklogItemId(backlogItemId);
                if (backlogItemApprove.getApplyIdOld() == null) {
                    FindFlowVO<ApplyAuditVO> findFlowVO = new FindFlowVO<>();

                    Long applyId = backlogItemApprove.getApplyId();
                    Optional<Eligible> eligibleOpt = eligibleRepository.findById(applyId);
                    if (!eligibleOpt.isPresent()) {
                        return ResultBean.failedResultWithMsg("资格申请不存在");
                    }
                    Eligible eligible = eligibleOpt.get();

                    List<ApplyAudit> audits = applyAuditRepository.findByApplyId(applyId);// 流程明细表
                    if (audits == null || audits.isEmpty()) {
                        return ResultBean.failedResultWithMsg("审批流程不存在");
                    }

                    List<ApplyAuditVO> list = new ArrayList<>();
                    for (ApplyAudit audit : audits) {
                        ApplyAuditVO vo = new ApplyAuditVO();
                        vo.setId(audit.getId());
                        vo.setApplyId(audit.getApplyId());
                        vo.setAuditProcessId(audit.getAuditProcessId());
                        String currentAuditId = audit.getCurrentAuditId();
                        vo.setCurrentAuditId(currentAuditId);
                        if (StringUtils.isNotBlank(currentAuditId)) {
                            User user = userRepository.findUserById(currentAuditId);
                            vo.setCurrentAuditName(user.getName());
                            // 查询审批人所属企业名称
                            String deptName = userService.findUserEnterpriseName(user.getId());
                            vo.setDeptName(deptName);
                        } else {
                            vo.setCurrentAuditName("待设置");
                        }
                        vo.setAuditStatus(audit.getAuditStatus());
                        vo.setRemark(audit.getRemark());
                        vo.setAuditTime(audit.getAuditTime() == null ? "" : DateUtils.format(audit.getAuditTime(), DateUtils.FORMAT_DATETIME_14));
                        list.add(vo);
                    }

                    findFlowVO.setApplyUser(eligible.getName());
                    findFlowVO.setApplyTime(DateUtils.format(eligible.getApplyTime(), DateUtils.FORMAT_DATETIME_14));
                    findFlowVO.setApplyId(applyId);
                    findFlowVO.setApplyStatus(eligible.getApplyStatus());
                    findFlowVO.setData(list);
                    findFlowVO.setDataType(1);

                    return ResultBean.successfulResult(findFlowVO);
                } else {
                    FindFlowVO<ApplyAuditVO> findFlowVO = new FindFlowVO<>();

                    Long applyId = backlogItemApprove.getApplyIdOld();
                    Optional<EligibleOld> eligibleOpt = eligibleOldRepository.findById(applyId);
                    if (!eligibleOpt.isPresent()) {
                        return ResultBean.failedResultWithMsg("资格申请不存在");
                    }
                    EligibleOld eligible = eligibleOpt.get();

                    List<ApplyAuditOld> audits = applyAuditOldRepository.findByApplyId(applyId);// 流程明细表
                    if (audits == null || audits.isEmpty()) {
                        return ResultBean.failedResultWithMsg("审批流程不存在");
                    }

                    List<ApplyAuditVO> list = new ArrayList<>();
                    for (ApplyAuditOld audit : audits) {
                        ApplyAuditVO vo = new ApplyAuditVO();
                        vo.setId(audit.getId());
                        vo.setApplyId(audit.getApplyId());
                        vo.setAuditProcessId(audit.getAuditProcessId());
                        String currentAuditId = audit.getCurrentAuditId();
                        vo.setCurrentAuditId(currentAuditId);
                        if (StringUtils.isNotBlank(currentAuditId)) {
                            User user = userRepository.findUserById(currentAuditId);
                            vo.setCurrentAuditName(user.getName());
                            // 查询审批人所属企业名称
                            String deptName = userService.findUserEnterpriseName(user.getId());
                            vo.setDeptName(deptName);
                        } else {
                            vo.setCurrentAuditName("待设置");
                        }
                        vo.setAuditStatus(audit.getAuditStatus());
                        vo.setRemark(audit.getRemark());
                        vo.setAuditTime(audit.getAuditTime() == null ? "" : DateUtils.format(audit.getAuditTime(), DateUtils.FORMAT_DATETIME_14));
                        list.add(vo);
                    }

                    findFlowVO.setApplyUser(eligible.getName());
                    findFlowVO.setApplyTime(DateUtils.format(eligible.getApplyTime(), DateUtils.FORMAT_DATETIME_14));
                    findFlowVO.setApplyId(applyId);
                    findFlowVO.setApplyStatus(eligible.getApplyStatus());
                    findFlowVO.setData(list);
                    findFlowVO.setDataType(2);

                    return ResultBean.successfulResult(findFlowVO);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return ResultBean.failedResultOfException();
    }

    public ResultBean<FindFlowVO<ApplyAuditVO>> findFlow3(String accessToken, Long id, Long backlogItemId) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            FindFlowVO<ApplyAuditVO> findFlowVO = new FindFlowVO<>();
            Long applyId = 0L;
            if (id != null) {
                applyId = id;
            }
            if (backlogItemId != null) {
                BacklogItemApprove backlogItemApprove = backlogItemApproveRepository.findByBacklogItemId(backlogItemId);
                applyId = backlogItemApprove.getApplyId();
            }

            Optional<Eligible> eligibleOpt = eligibleRepository.findById(applyId);
            if (!eligibleOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("资格申请不存在");
            }
            Eligible eligible = eligibleOpt.get();

            List<ApplyAudit> audits = applyAuditRepository.findByApplyId(applyId);// 流程明细表
            if (audits == null || audits.isEmpty()) {
                return ResultBean.failedResultWithMsg("审批流程不存在");
            }

            // 更新流程审批人数据
            for (ApplyAudit audit : audits) {
                String currentAuditId = audit.getCurrentAuditId();
                if (StringUtils.isBlank(currentAuditId)) {
                    Long orgAreaId = audit.getOrgAreaId();
                    ApprovalProcessUser approvalProcessUser = approvalProcessUserRepository
                            .findByAreaIdAndStatus(orgAreaId, 1);
                    if (approvalProcessUser != null) {
                        audit.setCurrentAuditId(approvalProcessUser.getAuditorUserId());
                        applyAuditRepository.save(audit);
                    }
                }
            }

            List<ApplyAuditVO> list = new ArrayList<>();
            for (ApplyAudit audit : audits) {
                ApplyAuditVO vo = new ApplyAuditVO();
                vo.setId(audit.getId());
                vo.setApplyId(audit.getApplyId());
                vo.setAuditProcessId(audit.getAuditProcessId());
                String currentAuditId = audit.getCurrentAuditId();
                vo.setCurrentAuditId(currentAuditId);
                if (StringUtils.isNotBlank(currentAuditId)) {
                    User user = userRepository.findUserById(currentAuditId);
                    vo.setCurrentAuditName(user.getName());
                    // 查询审批人所属企业名称
                    String deptName = userService.findUserEnterpriseName(user.getId());
                    vo.setDeptName(deptName);
                } else {
                    vo.setCurrentAuditName("待设置");
                }
                vo.setAuditStatus(audit.getAuditStatus());
                vo.setRemark(audit.getRemark());
                vo.setAuditTime(audit.getAuditTime() == null ? ""
                        : DateUtils.format(audit.getAuditTime(), DateUtils.FORMAT_DATETIME_14));
                list.add(vo);
            }

            findFlowVO.setApplyUser(eligible.getName());
            findFlowVO.setApplyTime(DateUtils.format(eligible.getApplyTime(), DateUtils.FORMAT_DATETIME_14));
            findFlowVO.setApplyId(applyId);
            findFlowVO.setApplyStatus(eligible.getApplyStatus());
            findFlowVO.setData(list);

            return ResultBean.successfulResult(findFlowVO);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional
    public ResultBean<Object> backOut(Long id) {
        try {
            if (id == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id为空");
            }

            eligibleRepository.updateById(id, EligibleApplyTypeEnum.BACKOUT.getValue());// 已撤销状态

            //删除资格审批待办事项
            List<BacklogItemApprove> approves = backlogItemApproveRepository.findByApplyId(id);
            if (!approves.isEmpty()) {
                BacklogItemApprove approve = approves.get(0);
                Long backlogItemId = approve.getBacklogItemId();
                backlogItemApproveRepository.deleteByApplyId(id);

                Optional<BacklogItem> optional = backlogItemRepository.findById(backlogItemId);
                if (optional.isPresent()){
                    backlogItemRepository.deleteById(backlogItemId);
                }
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<EligibleVO> findEligible2(Long id, Integer type) {
        try {
            log.info("EligibleService findEligible2, id={},type={}", id, type);

            if (type == null || type == 1) {
                return findEligible3(id);
            } else {
                return findEligible4(id);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return ResultBean.failedResultOfException();
    }

    public ResultBean<EligibleVO> findEligible3(Long id) {
        try {
            log.info("EligibleService findEligible3, id={}", id);
            if (id == null) {
                return ResultBean.failedResultOfParamWithMsg("资格申请id为空");
            }

            List<EligibleVO> query = jdbcTemplate.query("SELECT * FROM `saas_house_eligible_apply` a WHERE a.id = ?", new BeanPropertyRowMapper<EligibleVO>(EligibleVO.class), id);
            EligibleVO eligible = DataAccessUtils.uniqueResult(query);
            if (eligible == null) {
                return ResultBean.failedResultOfParamWithMsg("资格申请信息不存在");
            }

            eligible.setMonthIncomeAmount(eligible.getMonthIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
            eligible.setFamilyIncomeAmount(eligible.getFamilyIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
            eligible.setPerIncomeAmount(eligible.getPerIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));

            // 查询上传文件路径
            Map<Integer, List<String>> map = new HashMap<>();
            List<HouseApplyMaterial> materials = houseApplyMaterialRepository.findByApplyId(id);
            List<String> list1 = new ArrayList<>();
            List<String> list2 = new ArrayList<>();
            List<String> list3 = new ArrayList<>();
            List<String> list4 = new ArrayList<>();
            List<String> list5 = new ArrayList<>();
            List<String> list6 = new ArrayList<>();
            List<String> list7 = new ArrayList<>();
            for (HouseApplyMaterial material : materials) {
                Integer materialType = material.getMaterialType();
                if (materialType == 1) {
                    list1.add(material.getUrl());
                } else if (materialType == 2) {
                    list2.add(material.getUrl());
                } else if (materialType == 3) {
                    list3.add(material.getUrl());
                } else if (materialType == 4) {
                    list4.add(material.getUrl());
                } else if (materialType == 5) {
                    list5.add(material.getUrl());
                } else if (materialType == 6) {
                    list6.add(material.getUrl());
                } else if (materialType == 7) {
                    list7.add(material.getUrl());
                }
            }
            map.put(1, list1);
            map.put(2, list2);
            map.put(3, list3);
            map.put(4, list4);
            map.put(5, list5);
            map.put(6, list6);
            map.put(7, list7);
            eligible.setFileKeys(map);

            // 户籍地、申请区域
            List<Long> ids = new ArrayList<>();
            ids.add(eligible.getDomicileProvinceId());
            ids.add(eligible.getDomicileCityId());
            ids.add(eligible.getDomicileDistrictId());
            ids.add(eligible.getProvinceId());
            ids.add(eligible.getCityId());
            ids.add(eligible.getDistrictId());
            ids.add(eligible.getStreetId());
            ids.add(eligible.getCommunityId());
            Map<Long, String> areaMap = areaRepository.findByIdIn(ids).stream().collect(Collectors.toMap(Area::getId, Area::getName));
            if (!areaMap.isEmpty()) {
                eligible.setDomicileProvince(areaMap.get(eligible.getDomicileProvinceId()));
                eligible.setDomicileCity(areaMap.get(eligible.getDomicileCityId()));
                eligible.setDomicileDistrict(areaMap.get(eligible.getDomicileDistrictId()));
                eligible.setProvince(areaMap.get(eligible.getProvinceId()));
                eligible.setCity(areaMap.get(eligible.getCityId()));
                eligible.setDistrict(areaMap.get(eligible.getDistrictId()));
                eligible.setStreet(areaMap.get(eligible.getStreetId()));
                eligible.setCommunity(areaMap.get(eligible.getCommunityId()));
            }

            HouseApplyFlow flow = houseApplyFlowRepository.findByApplyCodeAndDataId(eligible.getApplyCode(),
                    eligible.getId().toString());
            if (flow != null) {
                eligible.setUpDataId(flow.getUpDataId());
                eligible.setNextDataId(flow.getNextDataId());
            }

            return ResultBean.successfulResult(eligible);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<EligibleVO> findEligible4(Long id) {
        try {
            log.info("EligibleService findEligible4, id={}", id);
            if (id == null) {
                return ResultBean.failedResultOfParamWithMsg("资格申请id为空");
            }

            List<EligibleVO> query = jdbcTemplate.query("SELECT * FROM `saas_house_eligible_apply_old` a WHERE a.id = ?", new BeanPropertyRowMapper<EligibleVO>(EligibleVO.class), id);
            EligibleVO eligible = DataAccessUtils.uniqueResult(query);
            if (eligible == null) {
                return ResultBean.failedResultOfParamWithMsg("资格申请信息不存在");
            }

            eligible.setMonthIncomeAmount(eligible.getMonthIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
            eligible.setFamilyIncomeAmount(eligible.getFamilyIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
            eligible.setPerIncomeAmount(eligible.getPerIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));

            // 查询上传文件路径
            Map<Integer, List<String>> map = new HashMap<>();
            List<HouseApplyMaterialOld> materials = houseApplyMaterialOldRepository.findByApplyId(id);
            List<String> list1 = new ArrayList<>();
            List<String> list2 = new ArrayList<>();
            List<String> list3 = new ArrayList<>();
            List<String> list4 = new ArrayList<>();
            List<String> list5 = new ArrayList<>();
            List<String> list6 = new ArrayList<>();
            List<String> list7 = new ArrayList<>();
            for (HouseApplyMaterialOld material : materials) {
                Integer materialType = material.getMaterialType();
                if (materialType == 1) {
                    list1.add(material.getUrl());
                } else if (materialType == 2) {
                    list2.add(material.getUrl());
                } else if (materialType == 3) {
                    list3.add(material.getUrl());
                } else if (materialType == 4) {
                    list4.add(material.getUrl());
                } else if (materialType == 5) {
                    list5.add(material.getUrl());
                } else if (materialType == 6) {
                    list6.add(material.getUrl());
                } else if (materialType == 7) {
                    list7.add(material.getUrl());
                }
            }
            map.put(1, list1);
            map.put(2, list2);
            map.put(3, list3);
            map.put(4, list4);
            map.put(5, list5);
            map.put(6, list6);
            map.put(7, list7);
            eligible.setFileKeys(map);

            // 户籍地、申请区域
            List<Long> ids = new ArrayList<>();
            ids.add(eligible.getDomicileProvinceId());
            ids.add(eligible.getDomicileCityId());
            ids.add(eligible.getDomicileDistrictId());
            ids.add(eligible.getProvinceId());
            ids.add(eligible.getCityId());
            ids.add(eligible.getDistrictId());
            ids.add(eligible.getStreetId());
            ids.add(eligible.getCommunityId());
            Map<Long, String> areaMap = areaRepository.findByIdIn(ids).stream().collect(Collectors.toMap(Area::getId, Area::getName));
            if (!areaMap.isEmpty()) {
                eligible.setDomicileProvince(areaMap.get(eligible.getDomicileProvinceId()));
                eligible.setDomicileCity(areaMap.get(eligible.getDomicileCityId()));
                eligible.setDomicileDistrict(areaMap.get(eligible.getDomicileDistrictId()));
                eligible.setProvince(areaMap.get(eligible.getProvinceId()));
                eligible.setCity(areaMap.get(eligible.getCityId()));
                eligible.setDistrict(areaMap.get(eligible.getDistrictId()));
                eligible.setStreet(areaMap.get(eligible.getStreetId()));
                eligible.setCommunity(areaMap.get(eligible.getCommunityId()));
            }

            HouseApplyFlowOld flow = houseApplyFlowOldRepository.findByApplyCodeAndDataId(eligible.getApplyCode(),
                    eligible.getId().toString());
            if (flow != null) {
                eligible.setUpDataId(flow.getUpDataId());
                eligible.setNextDataId(flow.getNextDataId());
            }

            return ResultBean.successfulResult(eligible);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<CohabitVO> findCohabit2(String applyCode, String id, Integer type) {
        try {
            log.info("EligibleService findCohabit2, id={},type={}", id, type);

            if (type == null || type == 1) {
                return findCohabit3(applyCode, id);
            } else {
                return findCohabit4(applyCode, id);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return ResultBean.failedResultOfException();
    }

    public ResultBean<CohabitVO> findCohabit3(String applyCode, String id) {
        try {
            if (StringUtils.isBlank(applyCode)) {
                return ResultBean.failedResultOfParamWithMsg("同批次编号为空");
            }
            if (StringUtils.isBlank(id)) {
                return ResultBean.failedResultOfParamWithMsg("同住人id为空");
            }

            CohabitVO cohabit = jdbcTemplate.queryForObject("SELECT c.*,a.province_id,a.city_id,a.district_id,a.street_id,a.community_id\n" +
                            "FROM `saas_house_eligible_apply_cohabit` c left join saas_house_eligible_apply a on c.apply_id = a.id WHERE c.id = ?",
                    new BeanPropertyRowMapper<>(CohabitVO.class), id);

            cohabit.setMonthIncomeAmount(cohabit.getMonthIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));

            Map<Integer, List<String>> map = new HashMap<>();
            List<HouseCohabitMaterial> materials = houseCohabitMaterialRepository.findByCohabitId(id);
            List<String> list1 = new ArrayList<>();
            List<String> list2 = new ArrayList<>();
            List<String> list3 = new ArrayList<>();
            List<String> list4 = new ArrayList<>();
            for (HouseCohabitMaterial material : materials) {
                Integer materialType = material.getMaterialType();
                if (materialType == 1) {
                    list1.add(material.getUrl());
                } else if (materialType == 2) {
                    list2.add(material.getUrl());
                } else if (materialType == 3) {
                    list3.add(material.getUrl());
                } else if (materialType == 4) {
                    list4.add(material.getUrl());
                }
            }
            map.put(1, list1);
            map.put(2, list2);
            map.put(3, list3);
            map.put(4, list4);
            cohabit.setFileKeys(map);

            // 户籍地、申请区域
            List<Long> ids = new ArrayList<>();
            ids.add(cohabit.getDomicileProvinceId());
            ids.add(cohabit.getDomicileCityId());
            ids.add(cohabit.getDomicileDistrictId());
            ids.add(cohabit.getProvinceId());
            ids.add(cohabit.getCityId());
            ids.add(cohabit.getDistrictId());
            ids.add(cohabit.getStreetId());
            ids.add(cohabit.getCommunityId());
            Map<Long, String> areaMap = areaRepository.findByIdIn(ids).stream()
                    .collect(Collectors.toMap(Area::getId, Area::getName));
            if (!areaMap.isEmpty()) {
                cohabit.setDomicileProvince(areaMap.get(cohabit.getDomicileProvinceId()));
                cohabit.setDomicileCity(areaMap.get(cohabit.getDomicileCityId()));
                cohabit.setDomicileDistrict(areaMap.get(cohabit.getDomicileDistrictId()));
                cohabit.setProvince(areaMap.get(cohabit.getProvinceId()));
                cohabit.setCity(areaMap.get(cohabit.getCityId()));
                cohabit.setDistrict(areaMap.get(cohabit.getDistrictId()));
                cohabit.setStreet(areaMap.get(cohabit.getStreetId()));
                cohabit.setCommunity(areaMap.get(cohabit.getCommunityId()));
            }

            HouseApplyFlow flow = houseApplyFlowRepository.findByApplyCodeAndDataId(applyCode, cohabit.getId());
            if (flow != null) {
                cohabit.setApplyCode(flow.getApplyCode());
                cohabit.setUpDataId(flow.getUpDataId());
                cohabit.setNextDataId(flow.getNextDataId());
            }

            return ResultBean.successfulResult(cohabit);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<CohabitVO> findCohabit4(String applyCode, String id) {
        try {
            if (StringUtils.isBlank(applyCode)) {
                return ResultBean.failedResultOfParamWithMsg("同批次编号为空");
            }
            if (StringUtils.isBlank(id)) {
                return ResultBean.failedResultOfParamWithMsg("同住人id为空");
            }

            CohabitVO cohabit = jdbcTemplate.queryForObject("SELECT c.*,a.province_id,a.city_id,a.district_id,a.street_id,a.community_id\n" +
                            "FROM `saas_house_eligible_apply_cohabit_old` c left join saas_house_eligible_apply_old a on c.apply_id = a.id WHERE c.id = ?",
                    new BeanPropertyRowMapper<>(CohabitVO.class), id);

            cohabit.setMonthIncomeAmount(cohabit.getMonthIncomeAmount().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));

            Map<Integer, List<String>> map = new HashMap<>();
            List<HouseCohabitMaterialOld> materials = houseCohabitMaterialOldRepository.findByCohabitId(id);
            List<String> list1 = new ArrayList<>();
            List<String> list2 = new ArrayList<>();
            List<String> list3 = new ArrayList<>();
            List<String> list4 = new ArrayList<>();
            for (HouseCohabitMaterialOld material : materials) {
                Integer materialType = material.getMaterialType();
                if (materialType == 1) {
                    list1.add(material.getUrl());
                } else if (materialType == 2) {
                    list2.add(material.getUrl());
                } else if (materialType == 3) {
                    list3.add(material.getUrl());
                } else if (materialType == 4) {
                    list4.add(material.getUrl());
                }
            }
            map.put(1, list1);
            map.put(2, list2);
            map.put(3, list3);
            map.put(4, list4);
            cohabit.setFileKeys(map);

            // 户籍地、申请区域
            List<Long> ids = new ArrayList<>();
            ids.add(cohabit.getDomicileProvinceId());
            ids.add(cohabit.getDomicileCityId());
            ids.add(cohabit.getDomicileDistrictId());
            ids.add(cohabit.getProvinceId());
            ids.add(cohabit.getCityId());
            ids.add(cohabit.getDistrictId());
            ids.add(cohabit.getStreetId());
            ids.add(cohabit.getCommunityId());
            Map<Long, String> areaMap = areaRepository.findByIdIn(ids).stream()
                    .collect(Collectors.toMap(Area::getId, Area::getName));
            if (!areaMap.isEmpty()) {
                cohabit.setDomicileProvince(areaMap.get(cohabit.getDomicileProvinceId()));
                cohabit.setDomicileCity(areaMap.get(cohabit.getDomicileCityId()));
                cohabit.setDomicileDistrict(areaMap.get(cohabit.getDomicileDistrictId()));
                cohabit.setProvince(areaMap.get(cohabit.getProvinceId()));
                cohabit.setCity(areaMap.get(cohabit.getCityId()));
                cohabit.setDistrict(areaMap.get(cohabit.getDistrictId()));
                cohabit.setStreet(areaMap.get(cohabit.getStreetId()));
                cohabit.setCommunity(areaMap.get(cohabit.getCommunityId()));
            }

            HouseApplyFlowOld flow = houseApplyFlowOldRepository.findByApplyCodeAndDataId(applyCode, cohabit.getId());
            if (flow != null) {
                cohabit.setApplyCode(flow.getApplyCode());
                cohabit.setUpDataId(flow.getUpDataId());
                cohabit.setNextDataId(flow.getNextDataId());
            }

            return ResultBean.successfulResult(cohabit);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }
    /**
     * 申请按钮状态,实现了前端页面的申请类型的展示和查询
     *
     * @param accessToken 权限鉴定
     * @return
     */
    public ResultBean<Object> applyStatus(String accessToken) {
        try {
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取登录类型：1企业用户登录 2普通用户登录
            Integer loginType = tokenRedisVo.getLoginType();
            //获取用户ID
            String userId = tokenRedisVo.getId();

            boolean flag = true;// 申请标识：true 可申请，false 不可申请
            if (loginType == 2) {
                //根据用户ID和类型查询出用户信息
                AppUser user = appUserService.findByIdAndStatus(userId, 1, loginType);
                //如果用户为空
                if (user == null) {
                    return ResultBean.failedResultWithMsg("用户不存在");
                }
                //获取用户身份证
                String cardNumber = user.getCardNumber();

                Long count1 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply` a \n" +
                        "where a.apply_status in (1,2,3,10) and a.card_number = ?", new Object[]{cardNumber}, Long.class);
                Long count2 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply_cohabit` c left join `saas_house_eligible_apply` a on c.apply_id = a.id\n" +
                        "where a.apply_status in (1,2,3,10) and c.card_number = ?", new Object[]{cardNumber}, Long.class);
                if (count1 + count2 > 0) {
                    flag = false;
                }
            }
            //把申请标识返回给前端页面
            return ResultBean.successfulResult(flag);
        } catch (Exception e) {
            //记录报错信息
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    @Transactional
    public ResultBean<Object> submit(String accessToken, Integer type, String applyCode) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();
            Long enterpriseId = tokenRedisVo.getEnterpriseId();

            if (type == null) {
                return ResultBean.failedResultOfParamWithMsg("申请类型为空");
            }
            if (StringUtils.isBlank(applyCode)) {
                return ResultBean.failedResultOfParamWithMsg("同批次编号为空");
            }

            Date date = new Date();
            List<HouseApplyFlow> flows = houseApplyFlowRepository.findByApplyCodeAndType(applyCode, 1);
            List<Long> dataIds = flows.stream().map(f -> Long.parseLong(f.getDataId())).distinct().collect(Collectors.toList());
            if (dataIds.isEmpty()) {
                return ResultBean.failedResultWithMsg("申请数据异常");
            }

            if (type == 1) {//个人申请
                Long dataId = dataIds.get(0);
                Optional<Eligible> eligibleOpt = eligibleRepository.findById(dataId);
                if (!eligibleOpt.isPresent()) {
                    return ResultBean.failedResultWithMsg("资格申请不存在");
                }
                Eligible eligible = eligibleOpt.get();

                //判断是否重复申请
                Long count1 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply` a \n" +
                        "where a.apply_status in (1,2,3,10) and a.card_number = ?", new Object[]{eligible.getCardNumber()}, Long.class);
                Long count2 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply_cohabit` c left join `saas_house_eligible_apply` a on c.apply_id = a.id\n" +
                        "where a.apply_status in (1,2,3,10) and c.card_number = ?", new Object[]{eligible.getCardNumber()}, Long.class);
                if (count1 + count2 > 0) {
                    return ResultBean.failedResultWithMsg("承租人信息已有公租房申请记录，请核实后提交");
                }

                // 修改成待审批状态
                eligibleRepository.updateApplyStatusByIds(dataIds, EligibleApplyTypeEnum.YET_APPROVE.getValue());
                //生成资格审批待办事项
                List<ApplyAudit> applyAudits = applyAuditRepository.findByApplyId(dataId);
                if (applyAudits.isEmpty()) {
                    return ResultBean.failedResultWithMsg("审批流程不存在");
                }
                ApplyAudit applyAudit = applyAudits.get(0);

                if (applyAudit.getCurrentAuditId() != null) {
                    BacklogItem backlogItem = new BacklogItem();
                    backlogItem.setType(BacklogItemTypeEnum.ELIGIBLE_APPROVE.getValue());
                    backlogItem.setTitle(eligible.getName() + "提交的公租房资格申请");
                    backlogItem.setBusinessStatus("待审批");
                    backlogItem.setHandleStatus(0);
                    backlogItem.setOperatorId(eligible.getMatchUserId());
                    backlogItem.setCreateTime(date);
                    BacklogItem save = backlogItemRepository.save(backlogItem);

                    BacklogItemApprove backlogItemApprove = new BacklogItemApprove();
                    backlogItemApprove.setBacklogItemId(save.getId());
                    backlogItemApprove.setApplyId(dataId);
                    backlogItemApprove.setApplyAuditId(applyAudit.getId());
                    backlogItemApprove.setUserId(applyAudit.getCurrentAuditId());
                    backlogItemApprove.setStatus(0);
                    backlogItemApproveRepository.save(backlogItemApprove);
                }
            } else if (type == 2) {//单位申请
                //true:需要审批  false:不需要审批
                boolean status = getApplyOrgAuditStatus(enterpriseId);

                for (Long dataId : dataIds) {
                    Optional<Eligible> eligibleOpt = eligibleRepository.findById(dataId);
                    if (!eligibleOpt.isPresent()) {
                        return ResultBean.failedResultWithMsg("资格申请不存在");
                    }
                    Eligible eligible = eligibleOpt.get();

                    //判断是否重复申请
                    Long count1 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply` a \n" +
                            "where a.apply_status in (1,2,3,10) and a.card_number = ?", new Object[]{eligible.getCardNumber()}, Long.class);
                    Long count2 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply_cohabit` c left join `saas_house_eligible_apply` a on c.apply_id = a.id\n" +
                            "where a.apply_status in (1,2,3,10) and c.card_number = ?", new Object[]{eligible.getCardNumber()}, Long.class);
                    if (count1 + count2 > 0) {
                        return ResultBean.failedResultWithMsg("承租人信息已有公租房申请记录，请核实后提交");
                    }

                    if (status) {
                        //修改资格申请成待审批状态
                        eligibleRepository.updateById(dataId, EligibleApplyTypeEnum.YET_APPROVE.getValue());
                        //生成资格审批待办事项
                        List<ApplyAudit> applyAudits = applyAuditRepository.findByApplyId(dataId);
                        if (applyAudits.isEmpty()) {
                            return ResultBean.failedResultWithMsg("审批流程不存在");
                        }
                        ApplyAudit applyAudit = applyAudits.get(0);

                        if (applyAudit.getCurrentAuditId() != null) {
                            BacklogItem backlogItem = new BacklogItem();
                            backlogItem.setType(BacklogItemTypeEnum.ELIGIBLE_APPROVE.getValue());
                            backlogItem.setTitle(eligible.getName() + "提交的公租房资格申请");
                            backlogItem.setBusinessStatus("待审批");
                            backlogItem.setHandleStatus(0);
                            backlogItem.setOperatorId(eligible.getMatchUserId());
                            backlogItem.setCreateTime(date);
                            BacklogItem save = backlogItemRepository.save(backlogItem);

                            BacklogItemApprove backlogItemApprove = new BacklogItemApprove();
                            backlogItemApprove.setBacklogItemId(save.getId());
                            backlogItemApprove.setApplyId(dataId);
                            backlogItemApprove.setApplyAuditId(applyAudit.getId());
                            backlogItemApprove.setUserId(applyAudit.getCurrentAuditId());
                            backlogItemApprove.setStatus(0);
                            backlogItemApproveRepository.save(backlogItemApprove);
                        }
                    } else {
                        //资格申请修改成审批通过状态，轮候配租状态
                        eligibleRepository.updateApplyStatusAndMatchStatusById(dataId, EligibleApplyTypeEnum.APPROVE.getValue(), EligibleMatchTypeEnum.WAIT_RENT.getValue());
                        //审批流程全部通过
                        jdbcTemplate.update("update saas_house_apply_audit set audit_status = 2,remark = '绿色通道，自动审核通过',audit_time = now() where apply_id = ?", dataId);
                        //生成轮候配租待办事项
                        BacklogItem backlogItem = new BacklogItem();
                        backlogItem.setOrgId(enterpriseId);
                        backlogItem.setType(BacklogItemTypeEnum.WAIT_RENT.getValue());
                        backlogItem.setTitle(eligible.getName() + "申请的公租房待轮候配租");
                        backlogItem.setContent("配租描述：请尽快轮候配租。");
                        backlogItem.setBusinessStatus("待轮候配租");
                        backlogItem.setHandleStatus(0);
                        backlogItem.setOperatorId(userId);
                        backlogItem.setCreateTime(date);
                        BacklogItem save = backlogItemRepository.save(backlogItem);

                        BacklogItemWaitRent backlogItemWaitRent = new BacklogItemWaitRent();
                        backlogItemWaitRent.setBacklogItemId(save.getId());
                        backlogItemWaitRent.setApplyId(dataId);
                        backlogItemWaitRentRepository.save(backlogItemWaitRent);
                    }
                }
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<Object> isCohabit(Long id) {
        try {
            if (id == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id为空");
            }

            boolean flag = false;
            List<Cohabit> cohabits = cohabitRepository.findByApplyId(id);
            if (cohabits != null && cohabits.size() != 0) {
                flag = true;
            }

            return ResultBean.successfulResult(flag);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 查询企业绿色通道状态
     *
     * @param orgId
     * @return
     * @author shun
     * @date 2021年6月30日
     */
    public boolean getApplyOrgAuditStatus(Long orgId) {
        String sql = "SELECT h.apply_auit_status as applyAuitStatus FROM saas_department_hierarchy h "
                + "LEFT JOIN saas_department_enterprise_tag_ref f ON h.id = f.dep_ref_id WHERE f.tag_id = 5 AND h.org_id = ?";

        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, orgId);
        if (list.isEmpty()) {
            log.info("查询企业绿色通过状态失败, 企业信息未找到, orgId={}", orgId);
            return true;
        }
        // 如果为空默认需要审批
        String applyAuitStatus = list.get(0).get("applyAuitStatus") == null ? "0" : list.get(0).get("applyAuitStatus").toString();
        // 0：关闭，需要审批；1：开启，不需要审批 默认0
        if ("0".equals(applyAuitStatus)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 编辑资格申请时，申请状态与待办事项处理
     *
     * @param eligible
     * @param date
     * @return
     * @author shun
     * @date 2021年7月12日
     */
    public ResultBean<Object> updateApplyData(Eligible eligible, Date date) {
        // 已撤销
        if (eligible.getApplyStatus() == EligibleApplyTypeEnum.BACKOUT.getValue()) {
            // 修改资格申请状态
            eligible.setApplyStatus(EligibleApplyTypeEnum.YET_APPROVE.getValue());
            // 重新生成待办事项
            List<ApplyAudit> applyAudits = applyAuditRepository.findByApplyId(eligible.getId());
            if (applyAudits.isEmpty()) {
                return ResultBean.failedResultWithMsg("审批流程不存在");
            }
            ApplyAudit applyAudit = applyAudits.get(0);

            if (applyAudit.getCurrentAuditId() != null) {
                // 查询是否已存在待办事项
                List<BacklogItemApprove> list = backlogItemApproveRepository.findByApplyIdAndApplyAuditId(eligible.getId(), applyAudit.getId());
                if (list.isEmpty()) {
                    BacklogItem backlogItem = new BacklogItem();
                    backlogItem.setType(BacklogItemTypeEnum.ELIGIBLE_APPROVE.getValue());
                    backlogItem.setTitle(eligible.getName() + "提交的公租房资格申请");
                    backlogItem.setBusinessStatus("待审批");
                    backlogItem.setHandleStatus(0);
                    backlogItem.setOperatorId(eligible.getMatchUserId());
                    backlogItem.setCreateTime(date);
                    BacklogItem save = backlogItemRepository.save(backlogItem);

                    BacklogItemApprove backlogItemApprove = new BacklogItemApprove();
                    backlogItemApprove.setBacklogItemId(save.getId());
                    backlogItemApprove.setApplyId(eligible.getId());
                    backlogItemApprove.setApplyAuditId(applyAudit.getId());
                    backlogItemApprove.setUserId(applyAudit.getCurrentAuditId());
                    backlogItemApprove.setStatus(0);
                    backlogItemApproveRepository.save(backlogItemApprove);
                }
            }
        }

        // 审核不通过
        if (eligible.getApplyStatus() == EligibleApplyTypeEnum.NOT_APPROVE.getValue()) {
            eligible.setApplyStatus(EligibleApplyTypeEnum.YET_APPROVE.getValue());
            // 重置审批流程状态
            List<ApplyAudit> applyAudits = applyAuditRepository.findByApplyId(eligible.getId());
            if (applyAudits.isEmpty()) {
                return ResultBean.failedResultWithMsg("审批流程不存在");
            }
            for (ApplyAudit applyAudit : applyAudits) {
                if (applyAudit.getSortby() == 1) {
                    applyAudit.setAuditStatus(1);
                } else {
                    applyAudit.setAuditStatus(0);
                }
                applyAudit.setRemark(null);
                applyAudit.setAuditTime(null);
            }

            applyAuditRepository.saveAll(applyAudits);
            // 删除之前待办事项
            List<BacklogItemApprove> approves = backlogItemApproveRepository.findByApplyId(eligible.getId());
            if (!approves.isEmpty()) {
                List<Long> itemIds = approves.stream().map(BacklogItemApprove::getBacklogItemId).distinct()
                        .collect(Collectors.toList());
                backlogItemApproveRepository.deleteByApplyId(eligible.getId());
                backlogItemRepository.deleteByIdIn(itemIds);
            }
            // 重新生成待办事项
            ApplyAudit applyAudit = applyAudits.get(0);
            if (applyAudit.getCurrentAuditId() != null) {
                BacklogItem backlogItem = new BacklogItem();
                backlogItem.setType(BacklogItemTypeEnum.ELIGIBLE_APPROVE.getValue());
                backlogItem.setTitle(eligible.getName() + "提交的公租房资格申请");
                backlogItem.setBusinessStatus("待审批");
                backlogItem.setHandleStatus(0);
                backlogItem.setOperatorId(eligible.getMatchUserId());
                backlogItem.setCreateTime(date);
                BacklogItem save = backlogItemRepository.save(backlogItem);

                BacklogItemApprove backlogItemApprove = new BacklogItemApprove();
                backlogItemApprove.setBacklogItemId(save.getId());
                backlogItemApprove.setApplyId(eligible.getId());
                backlogItemApprove.setApplyAuditId(applyAudit.getId());
                backlogItemApprove.setUserId(applyAudit.getCurrentAuditId());
                backlogItemApprove.setStatus(0);
                backlogItemApproveRepository.save(backlogItemApprove);
            }
        }
        eligibleRepository.save(eligible);

        return null;
    }

    @Transactional
    public ResultBean<Object> deleteEligible(Long id) {
        try {
            if (id == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id为空");
            }

            eligibleRepository.deleteById(id);
            cohabitRepository.deleteByApplyId(id);

            //删除资格审批待办事项
            List<BacklogItemApprove> approves = backlogItemApproveRepository.findByApplyId(id);
            if (!approves.isEmpty()) {
                BacklogItemApprove approve = approves.get(0);
                Long backlogItemId = approve.getBacklogItemId();
                backlogItemApproveRepository.deleteByApplyId(id);
                backlogItemRepository.deleteById(backlogItemId);
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<Object> verifyRepeatApply(Long id) {
        try {
            if (id == null) {
                return ResultBean.failedResultOfParamWithMsg("申请id为空");
            }

            Optional<Eligible> eligibleOpt = eligibleRepository.findById(id);
            if (!eligibleOpt.isPresent()) {
                return ResultBean.failedResultWithMsg("资格申请不存在");
            }
            Eligible eligible = eligibleOpt.get();
            String cardNumber = eligible.getCardNumber();

            int flag = 1;//标识：0不可编辑，1可编辑
            //查除当前申请是否还有待审批、审批中、已审批、变更中的资格申请
            Long count = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM saas_house_eligible_apply a\n" +
                    "WHERE a.card_number = ? AND a.apply_status IN (1,2,3,10) AND a.id != ?", new Object[]{cardNumber, id}, Long.class);

            if (count > 0) {
                flag = 0;
            }

            return ResultBean.successfulResult(flag);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }


}
